/*
* @(#)StreamParser
*
* Copyright (c) 2005-2009 by dvb.matt, All rights reserved.
*
* This file is part of ProjectX, a free Java based demux utility.
* By the authors, ProjectX is intended for educational purposes only,
* as a non-commercial test project.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* Support for SRT with font tags, W3C TTML and GPAC TTEXT
* added by Simon Liddicott
*
*/
package net.sourceforge.dvb.projectx.parser;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.io.PushbackInputStream;
import java.io.RandomAccessFile;
import java.io.ByteArrayOutputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Date;
import java.util.TimeZone;
import java.util.StringTokenizer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import net.sourceforge.dvb.projectx.common.Common;
import net.sourceforge.dvb.projectx.common.Resource;
import net.sourceforge.dvb.projectx.common.Keys;
import net.sourceforge.dvb.projectx.common.JobCollection;
import net.sourceforge.dvb.projectx.common.JobProcessing;
import net.sourceforge.dvb.projectx.io.RawFile;
import net.sourceforge.dvb.projectx.xinput.XInputFile;
import net.sourceforge.dvb.projectx.parser.CommonParsing;
import net.sourceforge.dvb.projectx.parser.StreamConverter;
import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer;
import net.sourceforge.dvb.projectx.parser.StreamProcessBase;
import net.sourceforge.dvb.projectx.parser.StreamProcessSubpicture;
import net.sourceforge.dvb.projectx.subtitle.Teletext;
import net.sourceforge.dvb.projectx.subtitle.UnicodeWriter;
import net.sourceforge.dvb.projectx.subtitle.Subpicture;
import net.sourceforge.dvb.projectx.subtitle.Sup2VobSub;
import net.sourceforge.dvb.projectx.thirdparty.Ifo;
/**
* main thread
*/
public class StreamProcessTeletext extends StreamProcessBase {
private final int MEGARADIO = 0;
private final int EXPORT_TEXT = 1;
private final int EXPORT_SC = 2;
private final int EXPORT_SUB = 3;
private final int EXPORT_SRT = 4;
private final int EXPORT_SSA = 5;
private final int EXPORT_SUP = 6;
private final int EXPORT_STL = 7;
private final int EXPORT_SON = 8;
private final int EXPORT_SRTC = 9;
private final int EXPORT_W3C = 10;
private final int EXPORT_GPAC = 11;
private byte tmp_byte_value = -1;
private int tmp_int_value = -1;
/**
*
*/
public StreamProcessTeletext(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream)
{
super();
String SubtitleExportFormat = collection.getSettings().getProperty(Keys.KEY_SubtitleExportFormat);
processStream(collection, xInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream, SubtitleExportFormat);
// 2nd export format, new run
SubtitleExportFormat = collection.getSettings().getProperty(Keys.KEY_SubtitleExportFormat_2);
if (!SubtitleExportFormat.equalsIgnoreCase("null"))
processStream(collection, xInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream, SubtitleExportFormat);
}
/**
* decoding teletext stream
*/
private void processStream(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream, String SubtitleExportFormat)
{
int[] SUP_Offset = { -1, -1 }; //1st + 2nd Offset
long size = 0;
boolean debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog);
boolean Message_2 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg2);
boolean ShowSubpictureWindow = collection.getSettings().getBooleanProperty(Keys.KEY_showSubpictureWindow);
boolean DecodeMegaradio = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_decodeMegaradio);
boolean ExportTextAsUnicode = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_exportTextAsUnicode);
boolean ExportTextAsUTF8 = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_exportTextAsUTF8);
boolean DecodeHiddenRows = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_decodeHiddenRows);
boolean KeepOriginalTimecode = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_keepOriginalTimecode);
boolean ExportAsVobSub = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_exportAsVobSub);
boolean BoxedMode = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_TtxExportBoxedOnly);
boolean TextAlignment = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_useTextAlignment);
// boolean SpecialTermination = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_specialTermination);
boolean SpecialTermination = true;
boolean KeepColourTable = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_keepColourTable);
String SubtitleFont = collection.getSettings().getProperty(Keys.KEY_SubtitleFont);
String Format_SUP_Values = collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_Format_SUP_Values);
JobProcessing job_processing = collection.getJobProcessing();
Subpicture subpicture = Common.getSubpictureClass();
Teletext teletext = Common.getTeletextClass();
if (ShowSubpictureWindow && (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[6].toString()) || SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[7].toString())))
Common.getGuiInterface().showSubpicture();
if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[7].toString()) || SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[6].toString())) // SUP + SON, set variables
SUP_Offset = subpicture.set(SubtitleFont, Format_SUP_Values, KeepColourTable);
ArrayList userdefined_pages = new ArrayList();
userdefined_pages.add(collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage1));
userdefined_pages.add(collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage2));
userdefined_pages.add(collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage3));
userdefined_pages.add(collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage4));
userdefined_pages.add(collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage5));
userdefined_pages.add(collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage6));
userdefined_pages.add(collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage7));
userdefined_pages.add(collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage8));
String page_list = "";
// read "777,888-890,150" etc
// read all pages and expand sparated pages 888,889,890 etc, if exists
for (int i = 0, ix = 0; i < userdefined_pages.size(); i++)
{
page_list = userdefined_pages.get(i).toString();
ix = page_list.indexOf(",");
if (ix > 0) // separated values
{
StringTokenizer st = new StringTokenizer(page_list, ",");
userdefined_pages.remove(i);
while (st.hasMoreTokens())
userdefined_pages.add(i, st.nextToken());
}
}
// read all pages and expand 888-890 etc, if exists
for (int i = 0, ix = 0, firstvalue = 0, lastvalue = 0; i < userdefined_pages.size(); i++)
{
page_list = userdefined_pages.get(i).toString();
ix = page_list.indexOf("-");
if (ix > 0) // values are in Hex
{
try {
firstvalue = Integer.parseInt(page_list.substring(0, ix), 16);
lastvalue = Integer.parseInt(page_list.substring(ix + 1), 16);
userdefined_pages.remove(i);
for (int j = lastvalue; j >= firstvalue; j--)
userdefined_pages.add(i, Integer.toHexString(j).toUpperCase());
} catch (Exception e) {
Common.setExceptionMessage(e);
}
}
}
for (int pn = 0; pn < userdefined_pages.size(); pn++)
{
String page = "0";
if (!DecodeMegaradio)
{
page = userdefined_pages.get(pn).toString();
if (page.equalsIgnoreCase("null"))
continue;
}
else
pn = userdefined_pages.size();
String fchild = xInputFile.getName();
String fparent = collection.getOutputNameParent(fchild);
size = xInputFile.length();
Common.getGuiInterface().initTtxPageMatrix(fchild);
teletext.clearEnhancements();
if (!DecodeMegaradio)
fparent += "[" + page + "]";
String ttxfile;
int subtitle_type;
if (DecodeMegaradio)
{
ttxfile = fparent + ".mgr";
subtitle_type = MEGARADIO;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[1].toString()))
{
ttxfile = fparent + ".sc";
subtitle_type = EXPORT_SC;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[2].toString()))
{
ttxfile = fparent + ".sub";
subtitle_type = EXPORT_SUB;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[3].toString()))
{
ttxfile = fparent + ".srt";
subtitle_type = EXPORT_SRT;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[8].toString()))
{
ttxfile = fparent + "[c].srt";
subtitle_type = EXPORT_SRTC;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[9].toString()))
{
ttxfile = fparent + "[W3C].xml";
subtitle_type = EXPORT_W3C;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[10].toString()))
{
ttxfile = fparent + "[GPAC].ttxt";
subtitle_type = EXPORT_GPAC;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[5].toString()))
{
ttxfile = fparent + ".ssa";
subtitle_type = EXPORT_SSA;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[7].toString()))
{
ttxfile = fparent + ".sup";
subtitle_type = EXPORT_SUP;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[4].toString()))
{
ttxfile = fparent + ".stl";
subtitle_type = EXPORT_STL;
}
else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[6].toString())) //placeholder for .son export
{
ttxfile = fparent + ".ssa"; //.son
subtitle_type = EXPORT_SSA; // 8
}
else if (SubtitleExportFormat.equalsIgnoreCase("null"))
continue;
else // free format
{
ttxfile = fparent + ".txt";
subtitle_type = EXPORT_TEXT;
}
Common.setMessage("");
Common.setMessage(Resource.getString("teletext.msg.output") + " " + ttxfile.substring(ttxfile.length() - 3));
if (ExportTextAsUnicode && subtitle_type != EXPORT_SUP)
Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_exportTextAsUnicode[0]));
if (ExportTextAsUTF8 && subtitle_type != EXPORT_SUP)
Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_exportTextAsUTF8[0]));
if (DecodeHiddenRows)
Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_decodeHiddenRows[0]));
if (BoxedMode)
Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_TtxExportBoxedOnly[0]));
if (KeepOriginalTimecode)
Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_keepOriginalTimecode[0]));
// if (SpecialTermination)
// Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_specialTermination[0]));
if (KeepColourTable)
Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_keepColourTable[0]));
DateFormat timeformat_1 = new SimpleDateFormat("HH:mm:ss.SSS");
timeformat_1.setTimeZone(TimeZone.getTimeZone("GMT+0:00"));
DateFormat timeformat_2 = new SimpleDateFormat("HH:mm:ss,SSS");
timeformat_2.setTimeZone(TimeZone.getTimeZone("GMT+0:00"));
boolean vptsdata = false;
boolean ptsdata = false;
boolean write = false;
boolean loadpage = false;
boolean valid = false;
long count = 0;
long time_difference = 0;
long source_pts = 0;
long startPoint = 0;
int page_value = subtitle_type == MEGARADIO ? 0x800 : Integer.parseInt(page, 16);
int x = 0;
int seiten = 0;
int v = 0;
int w = 0;
String page_number = "";
String subpage_number = "";
char txline[];
try {
PushbackInputStream in = new PushbackInputStream(xInputFile.getInputStream(), 94);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(ttxfile), 655350);
ByteArrayOutputStream byte_buffer = new ByteArrayOutputStream();
UnicodeWriter print_buffer = new UnicodeWriter(byte_buffer, ExportTextAsUnicode, ExportTextAsUTF8);
Common.setMessage(Resource.getString("teletext.msg.tmpfile", xInputFile.getName(), "" + size));
Common.setMessage(Resource.getString("teletext.msg.search") + " " + (subtitle_type == MEGARADIO ? Resource.getString("teletext.msg.megaradio") : Resource.getString("teletext.msg.page") + " " + page));
Common.updateProgressBar(Resource.getString("teletext.progress") + " " + (subtitle_type == MEGARADIO ? Resource.getString("teletext.msg.megaradio") : Resource.getString("teletext.msg.page") + " " + page), 0, 0);
long[] pts_value = {0};
long[] pts_position = {0};
long[] video_pts_value = {0};
long[] vtime = {0};
Common.getGuiInterface().showExportStatus(Resource.getString("teletext.status"), seiten);
long[][] obj = loadTempOtherPts(filename_pts, "teletext.msg.discard", "audio.msg.pts.firstonly", "teletext.msg.pts.start_end", "teletext.msg.pts.missed", CommonParsing.TELETEXT, false, debug);
if (obj != null)
{
pts_value = obj[0];
pts_position = obj[1];
ptsdata = true;
obj = null;
}
obj = loadTempVideoPts(videofile_pts, debug);
if (obj != null)
{
video_pts_value = obj[0];
vtime = obj[1];
vptsdata = true;
obj = null;
}
// 1st line
switch (subtitle_type)
{
case EXPORT_SC:
print_buffer.println("Subtitle File Mark:"+((CommonParsing.getVideoFramerate()==3600L) ? "2" : "1"));
print_buffer.flush();
byte_buffer.writeTo(out);
byte_buffer.reset();
break;
case EXPORT_W3C:
String[] W3Chead = teletext.getW3CHead();
for (int a = 0; a < W3Chead.length; a++)
print_buffer.println(W3Chead[a]);
print_buffer.flush();
byte_buffer.writeTo(out);
byte_buffer.reset();
break;
case EXPORT_GPAC:
String[] GPAChead = teletext.getGPACHead();
for (int a = 0; a < GPAChead.length; a++)
print_buffer.println(GPAChead[a]);
print_buffer.flush();
byte_buffer.writeTo(out);
byte_buffer.reset();
break;
case EXPORT_SSA:
String[] SSAhead = teletext.getSSAHead();
for (int a = 0; a < SSAhead.length; a++)
print_buffer.println(SSAhead[a]);
print_buffer.flush();
byte_buffer.writeTo(out);
byte_buffer.reset();
break;
case EXPORT_STL:
String[] STLhead = teletext.getSTLHead(Common.getVersionName() + " on " + DateFormat.getDateInstance(DateFormat.MEDIUM).format(new Date(System.currentTimeMillis())));
for (int a = 0; a < STLhead.length; a++)
print_buffer.println(STLhead[a]);
print_buffer.flush();
byte_buffer.writeTo(out);
byte_buffer.reset();
break;
case EXPORT_SON: //DM14052004 081.7 int02 add, still unused!
String[] SONhead = teletext.getSONHead(new File(ttxfile).getParent(), (long)CommonParsing.getVideoFramerate());
for (int a = 0; a < SONhead.length; a++)
print_buffer.println(SONhead[a]);
print_buffer.flush();
byte_buffer.writeTo(out);
byte_buffer.reset();
}
if (vptsdata && ptsdata)
{
int jump = checkPTSMatch(video_pts_value, pts_value);
if (jump < 0)
{
Common.setMessage(Resource.getString("teletext.msg.pts.mismatch"));
vptsdata = false;
x = 0;
}
else
x = jump;
}
x = 0; //start at 0
if (ptsdata)
{
source_pts = pts_value[x];
startPoint = pts_position[x];
if (vptsdata)
{
Common.setMessage(Resource.getString("teletext.msg.adjust.at.video"));
time_difference = video_pts_value[0];
}
else
{
Common.setMessage(Resource.getString("teletext.msg.adjust.at.own"));
time_difference = 0;
}
}
while (count < startPoint)
count += in.skip(startPoint-count);
boolean missing_syncword = false;
boolean vps = false;
boolean wss = false;
boolean page_match = false;
boolean lastpage_match = false;
int row = -1;
int magazine = -1;
int vbi = 0;
int character_set = 0;
int data_unit_id = -1;
int required_data_unit_id = -1;
byte packet[] = new byte[48];
Hashtable load_buffer = new Hashtable();
Hashtable write_buffer = new Hashtable();
Hashtable flags = new Hashtable();
ArrayList picture_String = new ArrayList();
String provider = "";
String program_title = "";
String vps_str = "";
String wss_str = "";
int character_count = 0;
readloop:
while ( count < size )
{
Common.updateProgressBar(count, size);
while (pause())
{}
if (CommonParsing.isProcessCancelled())
{
CommonParsing.setProcessCancelled(false);
job_processing.setSplitSize(0);
break readloop;
}
in.read(packet);
if (packet[1] != 0x2C && packet[47] != 0x2C && packet[1] != 0x5A && (0xFF & packet[1]) != 0x88 && (0xFF & packet[1]) != 0xFF)
{
if (Message_2 && !missing_syncword)
Common.setMessage(Resource.getString("teletext.msg.syncword.lost") + " " + count);
missing_syncword = true;
count++;
in.unread(packet, 1, 47);
continue readloop;
}
/**
* stuffing packet with size 0x5A + 2
*/
else if (packet[1] == 0x5A && packet[0] == -1)
{
in.skip(0x5C - 48);
count += 0x5C;
continue readloop;
}
/**
* stuffing packet with size 0x88 + 2
*/
else if ((0xFF & packet[1]) == 0x88 && packet[0] == -1)
{
in.skip(0x8A - 48);
count += 0x8A;
continue readloop;
}
/**
* stuffing packet without size value, skips std packet size 46
*/
else if (packet[1] == -1 && packet[0] == -1)
{
in.unread(packet, 46, 2);
count += 0x2E;
continue readloop;
}
else
in.unread(packet, 46, 2);
if (Message_2 && missing_syncword)
Common.setMessage(Resource.getString("teletext.msg.syncword.found") + " " + count);
missing_syncword = false;
count += 46;
vps = false;
wss = false;
valid = false;
data_unit_id = 0xFF & packet[0];
switch (data_unit_id)
{
case 2: // 0x02 EBU non subtitle data
case 3: // 0x03 EBU subtitle data
valid = true;
break;
case 0xC3: // VPS
valid = true;
vps = true;
break;
case 0xC4: // WSS
valid = true;
wss = true;
break;
case 0xFF: // hidden
if (DecodeHiddenRows)
valid = true;
break;
default: // others, unknown
if (debug)
System.out.println(" unkn_" + Integer.toHexString(0xFF & packet[0]) + "/" + (count - 46));
//continue readloop;
}
// logging
if (debug)
{
System.out.println();
System.out.println("pos: " + (count - 46));
for (int a = 0; a < 46; a++)
System.out.print(" " + ((0xFF & packet[a])<0x10 ? "0" : "") + Integer.toHexString(0xFF & packet[a]).toUpperCase());
System.out.println();
}
if (!valid)
continue readloop;
vbi = ((0x20 & packet[2]) != 0 ? 0 : 313) + (0x1F & packet[2]);
if (vps)
{
if ((0x3F & packet[2]) != 0x30)
continue readloop;
/**
* show vps status of VBI 16 in GUI
*/
String str = VBI.decodeVPS(packet, 2);
if (str != null && !str.equals(vps_str))
{
vps_str = str;
if (Common.getSettings().getBooleanProperty(Keys.KEY_showTtxHeader)) //interactive checkbox
Common.getGuiInterface().updateVpsLabel(vps_str);
Common.setMessage(Resource.getString("teletext.msg.vps", str) + " " + Common.formatTime_1(source_pts / 90));
}
continue readloop;
}
else if (wss)
{
if ((0x3F & packet[2]) != 0x37)
continue readloop;
if (!Common.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg5)) //interactive checkbox
continue readloop;
/**
* show wss status of VBI 23 in GUI
*/
String str = VBI.decodeWSS(packet, 2);
if (str != null && !str.equals(wss_str))
{
wss_str = str;
if (wss_str.length() == 0)
Common.setMessage("-> WSS Status - no change @ PTS " + Common.formatTime_1(source_pts / 90));
else
{
Common.setMessage("-> WSS Status - changed @ PTS " + Common.formatTime_1(source_pts / 90));
Common.setMessage(wss_str);
}
}
continue readloop;
}
else
{
tmp_int_value = (teletext.hamming_8_4(packet[4]))<<4 | teletext.hamming_8_4(packet[5]);
if (tmp_int_value < 0) // decode error
{
row = -1;
magazine = -1;
}
else
{
// row = 0xFF & teletext.bytereverse((byte)((0xF & teletext.hamming_8_4(packet[4]))<<4 | (0xF & teletext.hamming_8_4(packet[5]))));
row = 0xFF & teletext.bytereverse((byte) tmp_int_value);
magazine = (7 & row) == 0 ? 8 : (7 & row);
row >>>= 3;
}
}
// X3/31.1 ttx provider
if (magazine == 3 && row == 31 && packet[7] == 0x40 && packet[8] == 0x57 && provider.equals(""))
{
provider = teletext.buildString(packet, 10, 34, 31, 0, 0, false).trim();
Common.setMessage(Resource.getString("teletext.msg.provider") + " " + provider);
}
// X8/30.0 program title
else if (magazine == 8 && row == 30 && packet[7] == (byte)0xA8)
{
String str = teletext.buildString(packet, 26, 20, 30, 0, 0, true).trim() + " ";
if (!str.equals(program_title))
{
program_title = str;
Common.setMessage(Resource.getString("teletext.msg.program") + " " + program_title);
}
}
if (row == 0)
{
int flag = 0;
for (int a = 0; a < 6; a++)
flag |= (0xF & teletext.bytereverse((byte) teletext.hamming_8_4(packet[8+a]) )>>>4 ) <<(a*4);
page_number = Integer.toHexString(0xF & teletext.bytereverse((byte) teletext.hamming_8_4(packet[7]) )>>>4 ).toUpperCase() +
Integer.toHexString(0xF & teletext.bytereverse((byte) teletext.hamming_8_4(packet[6]) )>>>4 ).toUpperCase();
int o[] = { 0xF, 7, 0xF, 3 };
subpage_number = "";
for (int a = 3; a > -1; a--)
subpage_number += Integer.toHexString(o[a] & flag>>>(a*4)).toUpperCase();
flags.put("data_unit_id", "" + data_unit_id);
flags.put("magazine", "" + magazine);
flags.put("page_number", page_number);
flags.put("subpage_number", subpage_number);
flags.put("news", "" + (1 & flag>>>14));
flags.put("subtitle", "" + (1 & flag>>>15));
flags.put("erase", "" + (1 & flag>>>7));
flags.put("suppressed_head", "" + (1 & flag>>>16));
flags.put("update", "" + (1 & flag>>>17));
flags.put("interrupt", "" + (1 & flag>>>18));
flags.put("inhibit", "" + (1 & flag>>>19));
flags.put("magazine_serial", "" + (1 & flag>>>20));
flags.put("character_set", "" + (7 & flag>>>21));
// page_number matches -- subpage_numer currently always accepted
if ( page.equalsIgnoreCase( Integer.toHexString(magazine) + page_number) )
{
character_set = 7 & flag>>>21;
page_match = true;
}
else
page_match = false;
Common.getGuiInterface().updateTtxPageMatrix("" + magazine + page_number);
// show header_line in GUI
if (Common.getSettings().getBooleanProperty(Keys.KEY_showTtxHeader) || debug)
{
String str = magazine + page_number + " " + subpage_number + " " + teletext.buildString(packet, 14, 32, 0, (7 & flag>>>21), 0, true) + " " + program_title;
if (Common.getSettings().getBooleanProperty(Keys.KEY_showTtxHeader)) //interactive checkbox
Common.getGuiInterface().updateTtxHeader(str);
if (debug)
System.out.println(str);
}
if (debug)
System.out.println(flags.toString());
}
if (ptsdata)
{
write = !vptsdata;
while (pts_position[x+1] != -1 && pts_position[x+1] <= count - 46)
{
x++;
source_pts = pts_value[x];
}
rangeloop:
while (vptsdata && v < video_pts_value.length) //pic_start_pts must be in range ATM
{
if (source_pts < video_pts_value[v])
{
//write_buffer.put("cut_in_time", "" + video_pts_value[v]); // save value for cuts
break rangeloop;
}
else if (source_pts == video_pts_value[v] || source_pts < video_pts_value[v+1])
{
write = true;
break rangeloop;
}
v += 2;
if (v < video_pts_value.length)
{
//write_buffer.put("cut_out_time", "" + video_pts_value[v-1]); // save value for cuts
time_difference += (video_pts_value[v] - video_pts_value[v-1]);
}
}
}
else
write = true;
// logging
if (debug)
System.out.println("pos "+ (count-46) + "/vbi "+vbi+"/ "+magazine+"-"+row+"-"+page_number+"-"+subpage_number+"/pts "+source_pts+"/ "+timeformat_1.format(new Date(source_pts/90))+"/ "+Integer.toHexString(page_value)+"/wr "+write+"/lo "+loadpage+"/lastp "+lastpage_match+"/pagm "+page_match+"/v "+(v<video_pts_value.length ? video_pts_value[v] : v));
if (row != 0 && magazine != page_value>>>8) //row > 0, but not of current magazine
continue readloop;
if (row == 0) //accept all 0-rows of all magazines till now
{
boolean interrupt_loading = false;
//stop loading if same magazine, but other page
//stop loading if interrupted_flag by any page only if magazine_serial == 1, means rows of diff. pages of multiple magazines don't overlap by sent order
if (page_match || magazine == page_value>>>8 || flags.get("magazine_serial").toString().equals("1") )
interrupt_loading = true;
if (debug)
System.out.println("int " + interrupt_loading +"/load "+ loadpage + "/wri "+ write + "/wb " + write_buffer.size() + "/lb " + load_buffer.size());
// page header does not interrupt an active loading
if (!interrupt_loading)
continue readloop;
// megaradio_mode, magazine 8 only, other magazines are already ignored before page check
if (subtitle_type == MEGARADIO)
{
switch (Integer.parseInt(page_number, 16))
{
case 0xA:
case 0xB:
case 0xC:
loadpage=true;
}
switch (Integer.parseInt(subpage_number, 16))
{
case 0x0D:
case 0x0E:
case 0x1C:
case 0x1D:
//case 0x2A:
case 0x2B:
case 0x2C:
case 0x2D:
loadpage=false;
}
continue readloop;
}
// row 0 defines out_time of current buffered page forced by an interrupt event,
// sets the out_time of displaying and write it out
if (lastpage_match)
{
long out_time = source_pts - time_difference;
/**
* adapt out_time of page, if termination of it was detected later than 80ms after last row
*/
Object buffer_time = load_buffer.get("buffer_time");
if (buffer_time != null)
{
long l = Long.parseLong(buffer_time.toString());
if (source_pts - l > 7200)
{
out_time = l - time_difference + 7200;
if (debug)
System.out.println("termination for in_time too late, new out_time: " + out_time);
}
}
if (write) //buffered page can be written
{
write_buffer.put("out_time", "" + out_time);
while (true)
{
character_count = 0;
if ( !write_buffer.containsKey("active") )
break;
if ( !write_buffer.containsKey("in_time") )
break;
//start + end equals ?
if ( write_buffer.get("in_time").toString().equals(write_buffer.get("out_time").toString()) )
break;
switch (subtitle_type)
{
case EXPORT_TEXT: // free
print_buffer.print( "in_" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ));
print_buffer.println( "|out_" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ));
break;
case EXPORT_SC: // SC
print_buffer.print( teletext.SMPTE( timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + "&");
print_buffer.print( teletext.SMPTE( timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + "#");
break;
case EXPORT_SUB: // SUB
print_buffer.print( "{" + ( (long)(Long.parseLong( write_buffer.get("in_time").toString()) / CommonParsing.getVideoFramerate())) + "}");
print_buffer.print( "{" + ( (long)(Long.parseLong( write_buffer.get("out_time").toString()) / CommonParsing.getVideoFramerate())) + "}");
break;
case EXPORT_SRT: // SRT
case EXPORT_SRTC: // SRT colored
print_buffer.println( "" + (seiten + 1));
print_buffer.print( timeformat_2.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ));
print_buffer.println(" --> " + timeformat_2.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ));
break;
case EXPORT_W3C: // W3C Timed-Text
print_buffer.print( "<p begin=\"" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ) + "\" end=\"" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ) + "\">" );
break;
case EXPORT_GPAC: // GPAC Timed-Text
print_buffer.print( "<TextSample sampleTime=\"" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ) + "\" text=\"'" );
break;
case EXPORT_SSA: // SSA
print_buffer.print( teletext.getSSALine()[0] + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ).substring(1, 11) + ",");
print_buffer.print( timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ).substring(1, 11) + teletext.getSSALine()[1]);
break;
case EXPORT_STL: // STL
print_buffer.print( teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + ",");
print_buffer.print( teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + ",");
break;
case EXPORT_SUP: // SUP
long sup_in_time = Long.parseLong( write_buffer.get("in_time").toString() );
if ( sup_in_time >= 0 )
{
for (int a = 1; a < 24; a++)
if ( write_buffer.containsKey("" + a) )
picture_String.add(write_buffer.get("" + a));
while (picture_String.size() > subpicture.getMaximumLines()) // max. lines as defined
picture_String.remove(0);
subpicture.createPictureFromTeletext( picture_String.toArray(), job_processing.getStatusStrings());
//byte_buffer.write( subpicture.writeRLE( sup_in_time, 0xB4)); // alias duration 1.800 sec if out_time is missing
//if ( write_buffer.containsKey("out_time") )
// out.write(subpicture.setTime( byte_buffer.toByteArray(), Long.parseLong( write_buffer.get("out_time").toString())));
int displaytime = write_buffer.containsKey("out_time") ? subpicture.setTime(sup_in_time, Long.parseLong(write_buffer.get("out_time").toString())) : 0xB4;
byte_buffer.write( subpicture.writeRLE(sup_in_time, displaytime));
out.write(byte_buffer.toByteArray());
}
picture_String.clear();
}
int b = 0;
for (int a = 1; subtitle_type != EXPORT_SUP && a < 24; a++)
{
if ( !write_buffer.containsKey("" + a) )
continue;
String str = write_buffer.get("" + a).toString();
switch (subtitle_type)
{
case EXPORT_TEXT: // free
case EXPORT_SRT: // SRT
case EXPORT_SRTC: // SRTC
print_buffer.println(str);
break;
case EXPORT_W3C: // W3C Timed Text
print_buffer.print( (b > 0 ? "<br />" : "") + str);
break;
case EXPORT_GPAC: // GPAC Timed Text
print_buffer.print( (b > 0 ? "''" : "") + str);
break;
case EXPORT_SC: // SC
print_buffer.print(str);
break;
case EXPORT_SUB: // SUB
case EXPORT_STL: // STL
print_buffer.print( (b > 0 ? "|" : "") + str);
break;
case EXPORT_SSA: // SSA
print_buffer.print( (b > 0 ? "\\n" : "") + str);
}
b++;
}
if (subtitle_type == EXPORT_W3C)
{
print_buffer.print("</p>");
}
if (subtitle_type == EXPORT_GPAC)
{
print_buffer.println("'\">");
for (int a = 1; a < 24; a++)
{
if ( !write_buffer.containsKey("color" + a) )
continue;
StringTokenizer colors = new StringTokenizer(write_buffer.get("color" + a).toString(), "|");
while (colors.hasMoreTokens()) {
print_buffer.println(colors.nextToken());
}
}
print_buffer.print("</TextSample>");
}
if (subtitle_type != EXPORT_SUP && b > 0)
{
print_buffer.println();
print_buffer.flush();
byte_buffer.writeTo(out);
}
seiten++;
Common.getGuiInterface().showExportStatus(Resource.getString("teletext.status"), seiten);
break;
}
}
byte_buffer.reset();
write_buffer.clear();
}
lastpage_match = page_match;
// row 0 defines completion of current page to buffer,
// sets the in_time of displaying but cannot write it w/o still unknown out_time
if (loadpage)
{
write_buffer.clear();
if (!vptsdata && time_difference == 0 && !KeepOriginalTimecode)
time_difference = source_pts;
long in_time = source_pts - time_difference;
boolean rows = false;
/**
* adapt in_time of page, if termination of it was detected later than 80ms after last row
*/
Object buffer_time = load_buffer.get("buffer_time");
if (buffer_time != null)
{
long l = Long.parseLong(buffer_time.toString());
if (source_pts - l > 7200)
{
in_time = l - time_difference + 7200;
if (debug)
System.out.println("termination too late, new in_time: " + in_time);
}
}
// copy keys+values to clear for next page, only row 1..23 used instead of 0..31
for (int a = 1; a < 24; a++)
{
if ( !load_buffer.containsKey("" + a) )
continue;
rows = true; // non blank page
write_buffer.put("" + a, load_buffer.get("" + a));
if ( !load_buffer.containsKey("color" + a) )
continue;
write_buffer.put("color" + a, load_buffer.get("color" + a));
}
if (rows && write) // if false, in_time has to be set/updated at synccheck above until an exported gop pts area
write_buffer.put("in_time", "" + in_time);
if (!rows)
lastpage_match = false;
else
write_buffer.put("active", "1");
teletext.clearEnhancements();
load_buffer.clear();
}
loadpage = page_match;
/**
* test 0903
* updates current timestamp of last packet
*/
if (SpecialTermination)
load_buffer.put("buffer_time", String.valueOf(source_pts));
// logging
if (debug)
System.out.println("lo " + loadpage + "/lp_p "+lastpage_match+"/pg_m "+page_match+"/wbuf: " + write_buffer.toString());
continue readloop;
}
// only rows > 0
// logging
if (debug)
System.out.println("load " + loadpage + "/lbuf " + load_buffer.toString());
// ignore if row is not of expected magazine
if (magazine != page_value>>>8)
continue readloop;
// load and filter re-defined chars from X26/0..15 triplets
if (row > 23 && subtitle_type != 0)
{
if (row == 29 || loadpage)
teletext.setEnhancements(packet, row, character_set);
continue readloop;
}
if (!loadpage)
continue readloop;
if (subtitle_type == MEGARADIO) // megaradio, simple decode the bytes of row 1..23
{
for (int b = (row == 1) ? 17: 0; row < 24 && b < 39; b++) // framebytes to MSB
out.write(teletext.bytereverse(packet[7+b]));
continue readloop;
}
// decode row 1..23 , 0=header, 24 fasttext labels, 25 supressedheader, >26 non text packets
String str = null;
int[] picture_data = null;
switch (subtitle_type)
{
case EXPORT_TEXT:
str = teletext.buildString(packet, 6, 40, row, character_set, 0, true, BoxedMode);
break;
case EXPORT_SC:
case EXPORT_STL:
case EXPORT_SUB:
case EXPORT_SRT:
str = teletext.buildString(packet, 6, 40, row, character_set, 0, true, BoxedMode).trim();
break;
case EXPORT_SRTC:
str = teletext.buildString(packet, 6, 40, row, character_set, 2, true, BoxedMode).trim();
break;
case EXPORT_W3C:
str = teletext.buildString(packet, 6, 40, row, character_set, 3, true, BoxedMode).trim();
break;
case EXPORT_GPAC:
str = teletext.buildString(packet, 6, 40, row, character_set, 0, true, BoxedMode).trim();
load_buffer.put("color" + row, teletext.buildString(packet, 6, 40, row, character_set, 4, true, BoxedMode, character_count).trim());
character_count += str.length();
str = escapeXml(str);
break;
case EXPORT_SSA:
str = teletext.buildString(packet, 6, 40, row, character_set, 1, true, BoxedMode).trim();
break;
case EXPORT_SUP:
picture_data = teletext.buildCharArray(packet, 6, 40, row, character_set, true, BoxedMode, TextAlignment);
}
if (str != null && !str.equals(""))
load_buffer.put("" + row, str);
else if (picture_data != null)
load_buffer.put("" + row, picture_data);
if (debug)
System.out.println("row " + row + ": " + str + "/lb " + load_buffer.size());
/**
* updates current timestamp of last packet
*/
load_buffer.put("buffer_time", String.valueOf(source_pts));
} // return to read next packet
//write out last page in buffer
if (!write_buffer.isEmpty() && write)
{
long out_time = (vptsdata ? video_pts_value[video_pts_value.length - 1] : source_pts) - time_difference;
write_buffer.put("out_time", "" + out_time);
while (true)
{
if ( !write_buffer.containsKey("active") || !write_buffer.containsKey("in_time") )
break;
switch (subtitle_type)
{
case EXPORT_TEXT: // free
print_buffer.print( "in_" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ));
print_buffer.println( "|out_" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ));
break;
case EXPORT_SC: // SC
print_buffer.print( teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + "&");
print_buffer.print( teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + "#");
break;
case EXPORT_SUB: // SUB
print_buffer.print( "{" + ( (long)(Long.parseLong( write_buffer.get("in_time").toString()) / CommonParsing.getVideoFramerate())) + "}");
print_buffer.print( "{" + ( (long)(Long.parseLong( write_buffer.get("out_time").toString()) / CommonParsing.getVideoFramerate())) + "}");
break;
case EXPORT_SRT: // SRT
case EXPORT_SRTC: // SRT colored
print_buffer.println( "" + (seiten + 1));
print_buffer.print( timeformat_2.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ));
print_buffer.println(" --> " + timeformat_2.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ));
break;
case EXPORT_W3C: // W3C Timed-Text
print_buffer.print( "<p begin=\"" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ) + "\" end=\"" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ) + "\">" );
break;
case EXPORT_GPAC: // GPAC Timed-Text
print_buffer.print( "<TextSample sampleTime=\"" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ) + "\" text=\"'" );
break;
case EXPORT_SSA: // SSA
print_buffer.print( teletext.getSSALine()[0] + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ).substring(1, 11) + ",");
print_buffer.print( timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ).substring(1, 11) + teletext.getSSALine()[1]);
break;
case EXPORT_STL: // STL
print_buffer.print( teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + ",");
print_buffer.print( teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + ",");
break;
case EXPORT_SUP: // SUP
long sup_in_time = Long.parseLong( write_buffer.get("in_time").toString() );
if ( sup_in_time >= 0 )
{
for (int a = 1; a < 24; a++)
if ( write_buffer.containsKey("" + a) )
picture_String.add(write_buffer.get("" + a));
while (picture_String.size() > subpicture.getMaximumLines())
picture_String.remove(0);
subpicture.createPictureFromTeletext( picture_String.toArray(), job_processing.getStatusStrings());
// byte_buffer.write( subpicture.writeRLE( sup_in_time, 0xB4)); // alias duration 2.000 sec if out_time is missing
// out.write(subpicture.setTime( byte_buffer.toByteArray(), Long.parseLong( write_buffer.get("out_time").toString())));
int displaytime = subpicture.setTime(sup_in_time, Long.parseLong(write_buffer.get("out_time").toString()));
byte_buffer.write( subpicture.writeRLE(sup_in_time, displaytime));
out.write(byte_buffer.toByteArray());
}
picture_String.clear();
}
int b = 0;
for (int a = 1; subtitle_type != EXPORT_SUP && a < 24; a++)
{
if ( !write_buffer.containsKey("" + a) )
continue;
String str = write_buffer.get("" + a).toString();
switch (subtitle_type)
{
case EXPORT_TEXT: // free
case EXPORT_SRT: // SRT
print_buffer.println(str);
break;
case EXPORT_SRTC: // SRT colored
print_buffer.println(str);
break;
case EXPORT_W3C: // W3C Timed Text
print_buffer.print( (b > 0 ? "<br />" : "") + str);
break;
case EXPORT_GPAC: // GPAC Timed Text
print_buffer.print( (b > 0 ? "''" : "") + str);
break;
case EXPORT_SC: // SC
print_buffer.print(str);
break;
case EXPORT_SUB: // SUB
case EXPORT_STL: // STL
print_buffer.print( (b > 0 ? "|" : "") + str);
break;
case EXPORT_SSA: // SSA
print_buffer.print( (b > 0 ? "\\n" : "") + str);
}
b++;
}
if (subtitle_type == EXPORT_W3C)
{
String[] W3Cfoot = teletext.getW3CFoot();
for (int a = 0; a < W3Cfoot.length; a++)
print_buffer.println(W3Cfoot[a]);
}
if (subtitle_type == EXPORT_GPAC)
{
print_buffer.println("'\">");
for (int a = 1; a < 24; a++)
{
if ( !write_buffer.containsKey("color" + a) )
continue;
StringTokenizer colors = new StringTokenizer(write_buffer.get("color" + a).toString(), "|");
while (colors.hasMoreTokens()) {
print_buffer.println(colors.nextToken());
}
}
String[] GPACfoot = teletext.getGPACFoot();
for (int a = 0; a < GPACfoot.length; a++)
print_buffer.println(GPACfoot[a]);
}
if (subtitle_type != EXPORT_SUP && b > 0)
{
print_buffer.println();
print_buffer.flush();
byte_buffer.writeTo(out);
}
seiten++;
Common.getGuiInterface().showExportStatus(Resource.getString("teletext.status"), seiten);
break;
}
}
if (debug)
System.out.println();
Common.setMessage(Resource.getString("teletext.msg.summary", "" + seiten, page));
if (seiten > 0)
Common.setMessage(Resource.getString("msg.newfile") + " " + ttxfile);
write_buffer.clear();
in.close();
print_buffer.flush();
print_buffer.close();
byte_buffer.flush();
byte_buffer.close();
out.flush();
out.close();
File ttxfile1 = new File(ttxfile);
if (subtitle_type != MEGARADIO && seiten==0)
ttxfile1.delete();
else if (subtitle_type == MEGARADIO)
{
String pts_file = fparent + ".pts";
RandomAccessFile log = new RandomAccessFile(pts_file, "rw");
log.writeLong(0L);
log.writeLong(0L);
log.close();
Common.setMessage(ttxfile);
Common.setMessage(Resource.getString("working.filetype", Keys.ITEMS_FileTypes[CommonParsing.ES_MPA_TYPE]));
// audiofile goes to synch methode
new StreamProcess(CommonParsing.MPEG_AUDIO, collection, ttxfile, pts_file, "mp", "-1");
new File(ttxfile).delete();
new File(pts_file).delete();
return;
}
else
{
if (subtitle_type == EXPORT_SUP)
Ifo.createIfo(ttxfile, subpicture.getUserColorTableArray());
job_processing.countMediaFilesExportLength(ttxfile1.length());
job_processing.addSummaryInfo(Resource.getString("teletext.summary", Common.adaptString(job_processing.countPictureStream(), 2), "" + seiten, "" + page, infoPTSMatch(filename_pts, videofile_pts, vptsdata, ptsdata)) + "'" + ttxfile1 + "'");
//vobsub
if (subtitle_type == EXPORT_SUP && ExportAsVobSub)
new Sup2VobSub(ttxfile, subpicture.getUserColorTableArray());
}
} catch (IOException e2) {
Common.setExceptionMessage(e2);
}
//2nd offset applies
if (subtitle_type == EXPORT_SUP && SUP_Offset[1] >= 0)
{
Common.setMessage("");
Common.setMessage(Resource.getString("teletext.msg.newrun") + ": " + SUP_Offset[1]);
StreamProcessSubpicture streamprocess = new StreamProcessSubpicture("[P1]");
streamprocess.set_XY_Offset(0, SUP_Offset[0] - SUP_Offset[1]); //offset x +- 0, y = 32 - 96 (= -64 e.g.)
streamprocess.processStream(collection, new XInputFile(new File(ttxfile)), CommonParsing.ES_TYPE);
}
} // end for
Common.updateProgressBar(size, size);
if (ShowSubpictureWindow)
Common.getGuiInterface().hideSubpicture();
}
/**
* Get String representation of the object.
*
* @return String representation of the object
*/
private String escapeXml(String str) {
str = replaceStringByString(str, "&", "&"); //1st
str = replaceStringByString(str, "\"", """);
str = replaceStringByString(str, "'", "'");
str = replaceStringByString(str, ">", ">");
str = replaceStringByString(str, "<", "<");
return str;
}
/**
* @return String, checked of arg1 and replaced with arg2 JDK 1.2.2
* compatibility, replacement of newer String.replaceAll()
*/
private String replaceStringByString(String name, String arg1, String arg2) {
if (name == null) return name;
StringBuffer sb = new StringBuffer(name);
for (int i = 0; (i = sb.toString().indexOf(arg1, i)) != -1;)
sb.replace(i, i + 2, arg2);
return sb.toString();
}
}