From c4af3a3da8c42612fc7bf1150e559dac4ca02522 Mon Sep 17 00:00:00 2001 From: girst Date: Mon, 4 Feb 2019 18:57:31 +0000 Subject: [PATCH] WIP: add VTXv4 file format support VTXv4 is used by the dvbtext tool, which fetches pages from live DVB-{T,S,C} teletext --- filemonitor.cpp | 6 ++++- ttxpage.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ ttxpage.h | 7 ++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/filemonitor.cpp b/filemonitor.cpp index f2a5ccf..a33254e 100644 --- a/filemonitor.cpp +++ b/filemonitor.cpp @@ -77,12 +77,16 @@ void FileMonitor::run() // Load the filenames into a list while ((dirp = readdir(dp)) != NULL) { - // Select only pages that might be teletext. tti or ttix at the moment. + // Select only pages that might be teletext. .tti, .ttix or .vtx at the moment. // strcasestr doesn't seem to be in my Windows compiler. #ifdef _WIN32 char* p=strstr(dirp->d_name,".tti"); + if (!p) + p=strstr(dirp->d_name,".vtx"); #else char* p=strcasestr(dirp->d_name,".tti"); + if (!p) + p=strcasestr(dirp->d_name,".vtx"); #endif // std::cerr << path << "/" << dirp->d_name << std::endl; if (p) diff --git a/ttxpage.cpp b/ttxpage.cpp index 6a67d3b..da5aeb6 100644 --- a/ttxpage.cpp +++ b/ttxpage.cpp @@ -56,6 +56,8 @@ TTXPage::TTXPage(std::string filename) : m_Init(); // Careful! We should move inits to the initialisation list and call the default constructor // Try all the possible formats. + m_Loaded |= m_LoadVTXv4(filename); + if (!m_Loaded) if (m_LoadTTI(filename)) { @@ -243,6 +245,63 @@ bool TTXPage::m_LoadVTX(std::string filename) return true; } +bool TTXPage::m_LoadVTXv4(std::string filename) +{ + // vtxv4 files as produced by dvbtext; see also: https://github.com/girst/ttxd -> src/dvbtext-src/ + char buf[100]; + int pageno, subpageno = 0; + TTXPage* p = this; + std::ifstream filein(filename.c_str(), std::ios::binary | std::ios::in); + + // read .vtx-header, must start with "VTXV4" (12 bytes) + filein.read(buf,12); + if (buf[0]!='V' || buf[1]!='T' || buf[2]!='X' || buf[3]!='V' || buf[4]!='4') + { + filein.close(); + return false; + } + pageno = buf[6]*256 + buf[7]; + p->SetPageNumber(pageno*0x100+subpageno); + + // VTXv4 format does not encode subpage-numbers. we can only infer them from the filename, which is usually (e.g. dvbtext) "PPP_SS.vtx". + sscanf(basename(filename.c_str()), "%d_%d.", &pageno, &subpageno); + if (subpageno > 1){ + //XXX: cannot handle this currently due to how Setm_SubPage works + return false; + } + p->Setm_SubPage(nullptr); + + // read teletext header (8 bytes) + filein.read(buf,8); + // national character replacements: (see spec clause 15.2) + int nat_rep = buf[7] & (1<<5 | 1<<3 | 1<<1); + if (nat_rep == 0x02) p->SetPageStatus(p->GetPageStatus() | 0x200); /* German */ + + // read status bar (32 bytes) + filein.read(buf,32); + char buf2[41]; + for (int i = 0; i < 40; i++) + buf2[i] = i<8?' ': buf[i+8]&0x7f; + buf2[40] = 0; + std::string s(buf2, 40); + p->SetRow(0, s); + + // read page content (23*40 bytes) + for (int i=1;i<24;i++) + { + filein.read(buf,40); + for (int i=0; i<40; i++) + buf[i] &= 0x7f; //remove parity bit + buf[40]=0; + std::string s(buf, 40); + p->SetRow(i,s); + } + + filein.close(); + TTXPage::pageChanged = false; + return true; +} + bool TTXPage::m_LoadEP1(std::string filename) { char buf[100]; diff --git a/ttxpage.h b/ttxpage.h index 4aa5a42..80e9044 100644 --- a/ttxpage.h +++ b/ttxpage.h @@ -264,6 +264,13 @@ class TTXPage std::string m_FormatPageNumber(TTXPage* p); /// \return the page number ready to write to file int findPageNumber(char* buf); bool m_Loaded; + + /** Load a VTXv$ page + * \param filename : The source file + * \return true if the page was loaded + */ + bool m_LoadVTXv4(std::string filename); + /** Load an EP1 page * \param filename : The source file * \return true if the page was loaded