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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user