MythTV master
teletextextractorreader.cpp
Go to the documentation of this file.
1// -*- Mode: c++ -*-
2
4
5void TeletextExtractorReader::PageUpdated(int page, int subpage)
6{
7 m_updatedPages.insert(qMakePair(page, subpage));
8 TeletextReader::PageUpdated(page, subpage);
9}
10
12 int page, int subpage, tt_line_array& page_ptr, int lang)
13{
14 m_updatedPages.insert(qMakePair(page, subpage));
15 TeletextReader::HeaderUpdated(page, subpage, page_ptr, lang);
16}
17
18/************************************************************************
19 * Everything below this message in this file is based on some VLC
20 * teletext code which was in turn based on some ProjectX teletext code.
21 ************************************************************************/
22
23/*****************************************************************************
24 * telx.c : Minimalistic Teletext subtitles decoder
25 *****************************************************************************
26 * Copyright (C) 2007 Vincent Penne
27 * Some code converted from ProjectX java dvb decoder (c) 2001-2005 by dvb.matt
28 * $Id: 2b01e6a460b7c3693bccd690e3dbc018832d2777 $
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
43 *****************************************************************************/
44
45/*
46 * My doc only mentions 13 national characters, but experiments show there
47 * are more, in france for example I already found two more (0x9 and 0xb).
48 *
49 * Conversion is in this order :
50 *
51 * 0x23 0x24 0x40 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x7b 0x7c 0x7d 0x7e
52 * (these are the standard ones)
53 * 0x08 0x09 0x0a 0x0b 0x0c 0x0d (apparently a control character) 0x0e 0x0f
54 */
55
56using ppi_natl_array = std::array<const uint16_t,21>;
57static const std::array<const ppi_natl_array,13> ppi_national_subsets
58{{
59 { 0x00a3, 0x0024, 0x0040, 0x00ab, 0x00bd, 0x00bb, 0x005e, 0x0023,
60 0x002d, 0x00bc, 0x00a6, 0x00be, 0x00f7 }, /* english, 000 */
61
62 { 0x0023, 0x0024, 0x00a7, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x005f,
63 0x00b0, 0x00e4, 0x00f6, 0x00fc, 0x00df }, /* german, 001 */
64
65 { 0x0023, 0x00a4, 0x00c9, 0x00c4, 0x00d6, 0x00c5, 0x00dc, 0x005f,
66 0x00e9, 0x00e4, 0x00f6, 0x00e5, 0x00fc
67 }, /* swedish, finnish, hungarian, 010 */
68
69 { 0x00a3, 0x0024, 0x00e9, 0x00b0, 0x00e7, 0x00bb, 0x005e, 0x0023,
70 0x00f9, 0x00e0, 0x00f2, 0x00e8, 0x00ec }, /* italian, 011 */
71
72 { 0x00e9, 0x00ef, 0x00e0, 0x00eb, 0x00ea, 0x00f9, 0x00ee, 0x0023,
73 0x00e8, 0x00e2, 0x00f4, 0x00fb, 0x00e7, 0x0000, 0x00eb, 0x0000,
74 0x00ef
75 }, /* french, 100 */
76
77 { 0x00e7, 0x0024, 0x00a1, 0x00e1, 0x00e9, 0x00ed, 0x00f3, 0x00fa,
78 0x00bf, 0x00fc, 0x00f1, 0x00e8, 0x00e0 }, /* portuguese, spanish, 101 */
79
80 { 0x0023, 0x016f, 0x010d, 0x0165, 0x017e, 0x00fd, 0x00ed, 0x0159,
81 0x00e9, 0x00e1, 0x011b, 0x00fa, 0x0161 }, /* czech, slovak, 110 */
82
83 { 0x0023, 0x00a4, 0x0162, 0x00c2, 0x015e, 0x0102, 0x00ce, 0x0131,
84 0x0163, 0x00e2, 0x015f, 0x0103, 0x00ee }, /* rumanian, 111 */
85
86 /* I have these tables too, but I don't know how they can be triggered */
87 { 0x0023, 0x0024, 0x0160, 0x0117, 0x0119, 0x017d, 0x010d, 0x016b,
88 0x0161, 0x0105, 0x0173, 0x017e, 0x012f }, /* lettish, lithuanian, 1000 */
89
90 { 0x0023, 0x0144, 0x0105, 0x005a, 0x015a, 0x0141, 0x0107, 0x00f3,
91 0x0119, 0x017c, 0x015b, 0x0142, 0x017a }, /* polish, 1001 */
92
93 { 0x0023, 0x00cb, 0x010c, 0x0106, 0x017d, 0x0110, 0x0160, 0x00eb,
94 0x010d, 0x0107, 0x017e, 0x0111, 0x0161
95 }, /* serbian, croatian, slovenian, 1010 */
96
97 { 0x0023, 0x00f5, 0x0160, 0x00c4, 0x00d6, 0x017e, 0x00dc, 0x00d5,
98 0x0161, 0x00e4, 0x00f6, 0x017e, 0x00fc }, /* estonian, 1011 */
99
100 { 0x0054, 0x011f, 0x0130, 0x015e, 0x00d6, 0x00c7, 0x00dc, 0x011e,
101 0x0131, 0x015f, 0x00f6, 0x00e7, 0x00fc }, /* turkish, 1100 */
102}};
103
104// utc-2 --> utf-8
105// this is not a general function, but it's enough for what we do here
106// the result buffer need to be at least 4 bytes long
107static void to_utf8(std::string &res, uint16_t ch)
108{
109 if(ch >= 0x80)
110 {
111 if(ch >= 0x800)
112 {
113 res = { static_cast<char>( (ch >> 12) | 0xE0),
114 static_cast<char>(((ch >> 6) & 0x3F) | 0x80),
115 static_cast<char>( (ch & 0x3F) | 0x80) };
116 }
117 else
118 {
119 res = { static_cast<char>((ch >> 6) | 0xC0),
120 static_cast<char>((ch & 0x3F) | 0x80) } ;
121 }
122 }
123 else
124 {
125 res = { static_cast<char>(ch) };
126 }
127}
128
133QString decode_teletext(int codePage, const tt_line_array& data)
134{
135 QString res;
136 std::string utf8 {};
137
138 const ppi_natl_array pi_active_national_set = ppi_national_subsets[codePage];
139
140 for (int i = 0; i < 40; ++i)
141 {
142 //int in = bytereverse(data[i]) & 0x7f;
143 int in = data[i] & 0x7f;
144 uint16_t out = 32;
145
146 switch (in)
147 {
148 /* special national characters */
149 case 0x23:
150 out = pi_active_national_set[0];
151 break;
152 case 0x24:
153 out = pi_active_national_set[1];
154 break;
155 case 0x40:
156 out = pi_active_national_set[2];
157 break;
158 case 0x5b:
159 out = pi_active_national_set[3];
160 break;
161 case 0x5c:
162 out = pi_active_national_set[4];
163 break;
164 case 0x5d:
165 out = pi_active_national_set[5];
166 break;
167 case 0x5e:
168 out = pi_active_national_set[6];
169 break;
170 case 0x5f:
171 out = pi_active_national_set[7];
172 break;
173 case 0x60:
174 out = pi_active_national_set[8];
175 break;
176 case 0x7b:
177 out = pi_active_national_set[9];
178 break;
179 case 0x7c:
180 out = pi_active_national_set[10];
181 break;
182 case 0x7d:
183 out = pi_active_national_set[11];
184 break;
185 case 0x7e:
186 out = pi_active_national_set[12];
187 break;
188
189 case 0x0a:
190 case 0x0b:
191 case 0x0d:
192 //wtf? looks like some kind of garbage for me
193 out = 32;
194 break;
195
196 default:
197 /* non documented national range 0x08 - 0x0f */
198 if (in >= 0x08 && in <= 0x0f)
199 {
200 out = pi_active_national_set[13 + in - 8];
201 break;
202 }
203
204 /* normal ascii */
205 if (in > 32 && in < 0x7f)
206 out = in;
207 }
208
209 /* handle undefined national characters */
210 if (out == 0)
211 out = '?'; //' ' or '?' ?
212
213 /* convert to utf-8 */
214 to_utf8(utf8, out);
215 res += QString::fromUtf8(utf8.c_str());
216 }
217
218 return res;
219}
220
221//QString DechiperTtxFlags(int flags) {
222// QString res;
223
224// if (flags & TP_SUPPRESS_HEADER)
225// res += "TP_SUPPRESS_HEADER ";
226// if (flags & TP_UPDATE_INDICATOR)
227// res += "TP_UPDATE_INDICATOR ";
228// if (flags & TP_INTERRUPTED_SEQ)
229// res += "TP_INTERRUPTED_SEQ ";
230// if (flags & TP_INHIBIT_DISPLAY)
231// res += "TP_INHIBIT_DISPLAY ";
232// if (flags & TP_MAGAZINE_SERIAL)
233// res += "TP_MAGAZINE_SERIAL ";
234// if (flags & TP_ERASE_PAGE)
235// res += "TP_ERASE_PAGE ";
236// if (flags & TP_NEWSFLASH)
237// res += "TP_NEWSFLASH ";
238// if (flags & TP_SUBTITLE)
239// res += "TP_SUBTITLE ";
240
241// return res.trimmed();
242//}
243
244/* vim: set expandtab tabstop=4 shiftwidth=4: */
void PageUpdated(int page, int subpage) override
void HeaderUpdated(int page, int subpage, tt_line_array &page_ptr, int lang) override
QSet< QPair< int, int > > m_updatedPages
virtual void HeaderUpdated(int page, int subpage, tt_line_array &page_ptr, int lang)
virtual void PageUpdated(int page, int subpage)
unsigned short uint16_t
Definition: iso6937tables.h:3
QString decode_teletext(int codePage, const tt_line_array &data)
Get decoded ttx as a string.
static void to_utf8(std::string &res, uint16_t ch)
static const std::array< const ppi_natl_array, 13 > ppi_national_subsets
std::array< const uint16_t, 21 > ppi_natl_array
std::array< uint8_t, 40 > tt_line_array