Fix language detection bit swap in T42 header parsing

Correctly map C12 and C13 control bits to fix misidentification of Swedish/Finnish (010) and German (001).
Also ensures Page model, Renderer, and UI properly propagate and display the detected language.
This commit is contained in:
2026-01-11 11:40:20 +01:00
parent 783e5006f7
commit 8c393c8f9e
4 changed files with 37 additions and 5 deletions

View File

@@ -43,10 +43,10 @@ def load_t42(file_path: str, progress_callback: Optional[Callable[[int, int], No
# or find the existing one if we want to support updates (but T42 usually is a stream capture). # or find the existing one if we want to support updates (but T42 usually is a stream capture).
# If it's an editor file, it's likely sequential. # If it's an editor file, it's likely sequential.
p_num, sub_code = parse_header(packet.data) p_num, sub_code, language = parse_header(packet.data)
# Create new page # Create new page
new_page = Page(magazine=packet.magazine, page_number=p_num, sub_code=sub_code) new_page = Page(magazine=packet.magazine, page_number=p_num, sub_code=sub_code, language=language)
new_page.packets.append(packet) new_page.packets.append(packet)
service.pages.append(new_page) service.pages.append(new_page)
else: else:
@@ -209,4 +209,16 @@ def parse_header(data: bytearray):
sub_code = s1 | (s2 << 4) | (s3 << 8) | (s4 << 12) sub_code = s1 | (s2 << 4) | (s3 << 8) | (s4 << 12)
return page_num, sub_code # Control bits C12, C13, C14 are in Byte 8 (index 8)
# They determine the National Option (Language)
c_bits_2 = decode_hamming_8_4(data[8])
# Fix for Language Detection:
# It seems C12 and C13 are swapped in the Hamming decoding or file format relative to expected values.
# C12 is bit 0, C13 is bit 1.
# We swap them so D1 maps to C13 (Swedish bit) and D2 maps to C12 (German bit).
# Original: language = c_bits_2 & 0b111
language = ((c_bits_2 & 1) << 1) | ((c_bits_2 & 2) >> 1) | (c_bits_2 & 4)
return page_num, sub_code, language

View File

@@ -76,6 +76,7 @@ class Page:
magazine: int magazine: int
page_number: int # 00-99 page_number: int # 00-99
sub_code: int = 0 # Subpage code (0000 to 3F7F hex usually, simplest is 0-99 equivalent) sub_code: int = 0 # Subpage code (0000 to 3F7F hex usually, simplest is 0-99 equivalent)
language: int = 0 # National Option (0-7)
packets: List[Packet] = field(default_factory=list) packets: List[Packet] = field(default_factory=list)
@property @property

View File

@@ -139,6 +139,12 @@ class TeletextCanvas(QWidget):
def set_page(self, page: Page): def set_page(self, page: Page):
self.page = page self.page = page
# Set language from page header
if page:
self.subset_idx = page.language
else:
self.subset_idx = 0
self.cursor_x = 0 self.cursor_x = 0
self.cursor_y = 0 self.cursor_y = 0
self.redraw() self.redraw()

View File

@@ -128,9 +128,21 @@ class MainWindow(QMainWindow):
self.status_label = QLabel("Ready") self.status_label = QLabel("Ready")
self.status_bar.addWidget(self.status_label) self.status_bar.addWidget(self.status_label)
self.language_label = QLabel("Lang: English")
self.status_bar.addPermanentWidget(self.language_label)
self.language_names = ["English", "German", "Swedish/Finnish", "Italian", "French", "Portuguese/Spanish", "Turkish", "Romania"]
# Menus # Menus
self.create_menus() self.create_menus()
def update_language_label(self):
idx = self.canvas.subset_idx
if 0 <= idx < len(self.language_names):
self.language_label.setText(f"Lang: {self.language_names[idx]}")
else:
self.language_label.setText(f"Lang: Unknown ({idx})")
def set_modified(self, modified: bool): def set_modified(self, modified: bool):
self.is_modified = modified self.is_modified = modified
title = "Teletext Editor" title = "Teletext Editor"
@@ -222,8 +234,7 @@ class MainWindow(QMainWindow):
view_menu = menu_bar.addMenu("View") view_menu = menu_bar.addMenu("View")
lang_menu = view_menu.addMenu("Language") lang_menu = view_menu.addMenu("Language")
langs = ["English", "German", "Swedish/Finnish", "Italian", "French", "Portuguese/Spanish", "Turkish", "Romania"] for i, lang in enumerate(self.language_names):
for i, lang in enumerate(langs):
action = QAction(lang, self) action = QAction(lang, self)
action.setData(i) action.setData(i)
action.triggered.connect(self.set_language) action.triggered.connect(self.set_language)
@@ -236,6 +247,7 @@ class MainWindow(QMainWindow):
self.canvas.subset_idx = idx self.canvas.subset_idx = idx
self.canvas.redraw() self.canvas.redraw()
self.canvas.update() self.canvas.update()
self.update_language_label()
def prev_subpage(self): def prev_subpage(self):
count = self.subpage_combo.count() count = self.subpage_combo.count()
@@ -516,6 +528,7 @@ class MainWindow(QMainWindow):
if isinstance(page, Page): if isinstance(page, Page):
self.current_page = page self.current_page = page
self.canvas.set_page(page) self.canvas.set_page(page)
self.update_language_label()
self.canvas.setFocus() self.canvas.setFocus()
def insert_char(self, char_code): def insert_char(self, char_code):