fix: resolve rendering issues and incorrect page splitting in T42 loader
All checks were successful
Build Linux / Build Linux (push) Successful in 1m29s
Build Windows / Build Windows (push) Successful in 4m47s

This commit is contained in:
2026-02-21 13:33:29 +01:00
parent a9f3642254
commit 0d760ccb04
2 changed files with 11 additions and 15 deletions

View File

@@ -107,21 +107,18 @@ def load_t42(file_path: str, progress_callback: Optional[Callable[[int, int], No
# Robustness check for VHS captures: # Robustness check for VHS captures:
# If we see a row number that has already passed (e.g. Row 1 after Row 25) # If we see a row number that has already passed (e.g. Row 1 after Row 25)
# AND we didn't see a Row 0, it means a new page started but we missed the header. # AND we didn't see a Row 0, it means a new page started but we missed the header.
# We should split into a new Page object to avoid data corruption. # We only split on body rows (1-25) to avoid extension packets (26-31) triggering splits.
if target_page and row <= prev_row and row != prev_row: # Strictly less than (or handle duplicate rows?) if target_page and 1 <= row <= 25 and row < prev_row:
# In some captures, we might see the same row twice (Field 1/2).
# If it's the SAME row number, we just append (overwrites in renderer).
# If it's a LOWER row number, it's definitely a new cycle.
# Create a "Lost Header" page # Create a "Lost Header" page
# We use page_number=0xFF to indicate unknown, but we keep mag.
target_page = Page(magazine=mag, page_number=0xFF, sub_code=0, language=0) target_page = Page(magazine=mag, page_number=0xFF, sub_code=0, language=0)
service.pages.append(target_page) service.pages.append(target_page)
current_pages_by_mag[mag] = target_page current_pages_by_mag[mag] = target_page
if target_page: if target_page:
target_page.packets.append(packet) target_page.packets.append(packet)
last_row_by_mag[mag] = row # Only track body rows for sequence reversal detection
if 1 <= row <= 25:
last_row_by_mag[mag] = row
else: else:
# Packet without a header? Orphaned. Just keep in all_packets # Packet without a header? Orphaned. Just keep in all_packets
pass pass
@@ -266,9 +263,8 @@ def parse_header(data: bytearray):
sub_code = s1 | (s2 << 4) | (s3 << 8) | (s4 << 12) sub_code = s1 | (s2 << 4) | (s3 << 8) | (s4 << 12)
# Control bits C12, C13, C14 are in Byte 8 (index 8) # Control bits C12, C13, C14 are in Byte 13 (index 7 of data)
# They determine the National Option (Language) c_bits_2 = decode_hamming_8_4(data[7])
c_bits_2 = decode_hamming_8_4(data[8])
# Fix for Language Detection: # Fix for Language Detection:
# It seems C12 and C13 are swapped in the Hamming decoding or file format relative to expected values. # It seems C12 and C13 are swapped in the Hamming decoding or file format relative to expected values.

View File

@@ -69,10 +69,10 @@ class TeletextCanvas(QWidget):
self.flash_timer.timeout.connect(self.toggle_flash) self.flash_timer.timeout.connect(self.toggle_flash)
self.flash_timer.start(500) # 500ms toggle (1Hz flash rate) self.flash_timer.start(500) # 500ms toggle (1Hz flash rate)
# Teletext is 40 columns x 25 rows # Teletext is 40 columns x 26 rows (0-25)
# We will render to a fixed size QImage and scale it # We will render to a fixed size QImage and scale it
self.cols = 40 self.cols = 40
self.rows = 25 self.rows = 26
self.cell_w = 20 self.cell_w = 20
self.cell_h = 24 self.cell_h = 24
self.img_w = self.cols * self.cell_w self.img_w = self.cols * self.cell_w
@@ -237,13 +237,13 @@ class TeletextCanvas(QWidget):
# Pass 1: Backgrounds # Pass 1: Backgrounds
occlusion_mask = [False] * 40 occlusion_mask = [False] * 40
for r in range(25): for r in range(26):
packet = grid[r] packet = grid[r]
occlusion_mask = self.draw_row(painter, r, packet, draw_bg=True, draw_fg=False, occlusion_mask=occlusion_mask) occlusion_mask = self.draw_row(painter, r, packet, draw_bg=True, draw_fg=False, occlusion_mask=occlusion_mask)
# Pass 2: Foregrounds # Pass 2: Foregrounds
occlusion_mask = [False] * 40 occlusion_mask = [False] * 40
for r in range(25): for r in range(26):
packet = grid[r] packet = grid[r]
occlusion_mask = self.draw_row(painter, r, packet, draw_bg=False, draw_fg=True, occlusion_mask=occlusion_mask) occlusion_mask = self.draw_row(painter, r, packet, draw_bg=False, draw_fg=True, occlusion_mask=occlusion_mask)