diff --git a/sstv/decode.py b/sstv/decode.py index 6e74063..3d405fd 100644 --- a/sstv/decode.py +++ b/sstv/decode.py @@ -254,10 +254,10 @@ class SSTVDecoder(object): seq_start += self._align_sync(transmission[seq_start:]) pixel_time = self.mode.PIXEL_TIME - if self.mode.HAS_MERGE_SCAN: - # Robot mode has half-length second scan - if chan % 2 == 1: - pixel_time = self.mode.MERGE_PIXEL_TIME + if self.mode.HAS_HALF_SCAN: + # Robot mode has half-length second/third scans + if chan > 0: + pixel_time = self.mode.HALF_PIXEL_TIME centre_window_time = (pixel_time * window_factor) / 2 pixel_window = round(centre_window_time * 2 * @@ -289,6 +289,7 @@ class SSTVDecoder(object): width = self.mode.LINE_WIDTH height = self.mode.LINE_COUNT + channels = self.mode.CHAN_COUNT image = Image.new(col_mode, (width, height)) pixel_data = image.load() @@ -296,21 +297,35 @@ class SSTVDecoder(object): log_message("Drawing image data...") for y in range(height): - odd_line = y % 2 + odd_line = y % 2 for x in range(width): - if self.mode.COLOR == spec.COL_FMT.GBR: - pixel = (image_data[y][2][x], - image_data[y][0][x], - image_data[y][1][x]) - elif self.mode.COLOR == spec.COL_FMT.YUV: - pixel = (image_data[y][0][x], - image_data[y-(odd_line-1)][1][x], - image_data[y-odd_line][1][x]) - else: - pixel = (image_data[y][0][x], - image_data[y][1][x], - image_data[y][2][x]) + + if channels == 2: + + if self.mode.HAS_ALT_SCAN: + if self.mode.COLOR == spec.COL_FMT.YUV: + # R36 + pixel = (image_data[y][0][x], + image_data[y-(odd_line-1)][1][x], + image_data[y-odd_line][1][x]) + + elif channels == 3: + + if self.mode.COLOR == spec.COL_FMT.GBR: + # M1, M2, S1, S2, SDX + pixel = (image_data[y][2][x], + image_data[y][0][x], + image_data[y][1][x]) + elif self.mode.COLOR == spec.COL_FMT.YUV: + # R72 + pixel = (image_data[y][0][x], + image_data[y][2][x], + image_data[y][1][x]) + elif self.mode.COLOR == spec.COL_FMT.RGB: + pixel = (image_data[y][0][x], + image_data[y][1][x], + image_data[y][2][x]) pixel_data[x, y] = pixel diff --git a/sstv/spec.py b/sstv/spec.py index b623539..e74322f 100644 --- a/sstv/spec.py +++ b/sstv/spec.py @@ -34,7 +34,8 @@ class M1(object): WINDOW_FACTOR = 2.34 HAS_START_SYNC = False - HAS_MERGE_SCAN = False + HAS_HALF_SCAN = False + HAS_ALT_SCAN = False class M2(M1): @@ -81,7 +82,8 @@ class S1(object): WINDOW_FACTOR = 2.48 HAS_START_SYNC = True - HAS_MERGE_SCAN = False + HAS_HALF_SCAN = False + HAS_ALT_SCAN = False class S2(S1): @@ -121,7 +123,7 @@ class SDX(S2): LINE_TIME = SYNC_PULSE + 3 * CHAN_TIME PIXEL_TIME = SCAN_TIME / LINE_WIDTH - WINDOW_FACTOR = 1.01 + WINDOW_FACTOR = 0.98 class R36(object): @@ -131,7 +133,7 @@ class R36(object): LINE_WIDTH = 320 LINE_COUNT = 240 SCAN_TIME = 0.088000 - MERGE_SCAN_TIME = 0.044000 + HALF_SCAN_TIME = 0.044000 SYNC_PULSE = 0.009000 SYNC_PORCH = 0.003000 SEP_PULSE = 0.004500 @@ -144,16 +146,45 @@ class R36(object): CHAN_OFFSETS = [SYNC_PULSE + SYNC_PORCH] CHAN_OFFSETS.append(CHAN_OFFSETS[0] + CHAN_TIME + SEP_PORCH) - LINE_TIME = CHAN_OFFSETS[1] + MERGE_SCAN_TIME + LINE_TIME = CHAN_OFFSETS[1] + HALF_SCAN_TIME PIXEL_TIME = SCAN_TIME / LINE_WIDTH - MERGE_PIXEL_TIME = MERGE_SCAN_TIME / LINE_WIDTH + HALF_PIXEL_TIME = HALF_SCAN_TIME / LINE_WIDTH WINDOW_FACTOR = 7.70 HAS_START_SYNC = False - HAS_MERGE_SCAN = True + HAS_HALF_SCAN = True + HAS_ALT_SCAN = True + + +class R72(R36): + NAME = "Robot 72" + + LINE_WIDTH = 320 + SCAN_TIME = 0.138000 + HALF_SCAN_TIME = 0.069000 + SYNC_PULSE = 0.009000 + SYNC_PORCH = 0.003000 + SEP_PULSE = 0.004500 + SEP_PORCH = 0.001500 + + CHAN_COUNT = 3 + CHAN_TIME = SEP_PULSE + SCAN_TIME + HALF_CHAN_TIME = SEP_PULSE + HALF_SCAN_TIME + + CHAN_OFFSETS = [SYNC_PULSE + SYNC_PORCH] + CHAN_OFFSETS.append(CHAN_OFFSETS[0] + CHAN_TIME + SEP_PORCH) + CHAN_OFFSETS.append(CHAN_OFFSETS[1] + HALF_CHAN_TIME + SEP_PORCH) + + LINE_TIME = CHAN_OFFSETS[2] + HALF_SCAN_TIME + PIXEL_TIME = SCAN_TIME / LINE_WIDTH + HALF_PIXEL_TIME = HALF_SCAN_TIME / LINE_WIDTH + WINDOW_FACTOR = 4.88 + + HAS_ALT_SCAN = False VIS_MAP = {8: R36, + 12: R72, 40: M2, 44: M1, 56: S2,