<commit_before>#!/usr/bin/env python

from __future__ import division
from sstv import byte_to_freq, FREQ_BLACK, FREQ_WHITE, FREQ_VIS_START
from grayscale import GrayscaleSSTV
from itertools import chain


RED, GREEN, BLUE = range(3)

class ColorSSTV(GrayscaleSSTV):
    def on_init(self):
        self.pixels = self.image.load()

    def encode_line(self, line):
        msec_pixel = self.SCAN / self.WIDTH
        image = self.pixels
        for index in self.COLOR_SEQ:
            for item in self.before_channel(index):
                yield item
            for col in xrange(self.WIDTH):
                pixel = image[col, line]
                freq_pixel = byte_to_freq(pixel[index])
                yield freq_pixel, msec_pixel
            for item in self.after_channel(index):
                yield item

    def before_channel(self, index):
        return []

    after_channel = before_channel


class MartinM1(ColorSSTV):
    COLOR_SEQ = (GREEN, BLUE, RED)
    VIS_CODE = 0x2c
    WIDTH = 320
    HEIGHT = 256
    SYNC = 4.862
    SCAN = 146.432
    INTER_CH_GAP = 0.572

    def before_channel(self, index):
        if index == GREEN:
            yield FREQ_BLACK, self.INTER_CH_GAP

    def after_channel(self, index):
        yield FREQ_BLACK, self.INTER_CH_GAP


class MartinM2(MartinM1):
    VIS_CODE = 0x28
    WIDTH = 160
    SCAN = 73.216


class ScottieS1(MartinM1):
    VIS_CODE = 0x3c
    SYNC = 9
    INTER_CH_GAP = 1.5
    SCAN = 138.24 - INTER_CH_GAP

    def horizontal_sync(self):
        return []

    def before_channel(self, index):
        if index == RED:
            for item in MartinM1.horizontal_sync(self):
                yield item
        yield FREQ_BLACK, self.INTER_CH_GAP


class ScottieS2(ScottieS1):
    VIS_CODE = 0x38
    SCAN = 88.064 - ScottieS1.INTER_CH_GAP
    WIDTH = 160


class Robot36(ColorSSTV):
    VIS_CODE = 0x08
    WIDTH = 320
    HEIGHT = 240
    SYNC = 9
    INTER_CH_GAP = 4.5
    Y_SCAN = 88
    C_SCAN = 44
    PORCH = 1.5
    SYNC_PORCH = 3
    INTER_CH_FREQS = [None, FREQ_BLACK, FREQ_WHITE]

    def on_init(self):
        self.yuv = self.image.convert('YCbCr').load()

    def encode_line(self, line):
        pixels = [self.yuv[col, line] for col in xrange(self.WIDTH)]
        channel = (line % 2) + 1
        y_pixel_time = self.Y_SCAN / self.WIDTH
        uv_pixel_time = self.C_SCAN / self.WIDTH
        return chain(
                [(FREQ_BLACK, self.SYNC_PORCH)],
                ((byte_to_freq(p[0]), y_pixel_time) for p in pixels),
                [(self.INTER_CH_FREQS[channel], self.INTER_CH_GAP),
                    (FREQ_VIS_START, self.PORCH)],
                ((byte_to_freq(p[channel]), uv_pixel_time) for p in pixels))


MODES = (MartinM1, MartinM2, ScottieS1, ScottieS2, Robot36)<commit_msg>Add "high"-resolution modes Pasokon P3, P5 and P7 Tested against MMSSTV and HamRadio software<commit_after>#!/usr/bin/env python

from __future__ import division
from sstv import byte_to_freq, FREQ_BLACK, FREQ_WHITE, FREQ_VIS_START
from grayscale import GrayscaleSSTV
from itertools import chain


RED, GREEN, BLUE = range(3)

class ColorSSTV(GrayscaleSSTV):
    def on_init(self):
        self.pixels = self.image.load()

    def encode_line(self, line):
        msec_pixel = self.SCAN / self.WIDTH
        image = self.pixels
        for index in self.COLOR_SEQ:
            for item in self.before_channel(index):
                yield item
            for col in xrange(self.WIDTH):
                pixel = image[col, line]
                freq_pixel = byte_to_freq(pixel[index])
                yield freq_pixel, msec_pixel
            for item in self.after_channel(index):
                yield item

    def before_channel(self, index):
        return []

    after_channel = before_channel


class MartinM1(ColorSSTV):
    COLOR_SEQ = (GREEN, BLUE, RED)
    VIS_CODE = 0x2c
    WIDTH = 320
    HEIGHT = 256
    SYNC = 4.862
    SCAN = 146.432
    INTER_CH_GAP = 0.572

    def before_channel(self, index):
        if index == GREEN:
            yield FREQ_BLACK, self.INTER_CH_GAP

    def after_channel(self, index):
        yield FREQ_BLACK, self.INTER_CH_GAP


class MartinM2(MartinM1):
    VIS_CODE = 0x28
    WIDTH = 160
    SCAN = 73.216


class ScottieS1(MartinM1):
    VIS_CODE = 0x3c
    SYNC = 9
    INTER_CH_GAP = 1.5
    SCAN = 138.24 - INTER_CH_GAP

    def horizontal_sync(self):
        return []

    def before_channel(self, index):
        if index == RED:
            for item in MartinM1.horizontal_sync(self):
                yield item
        yield FREQ_BLACK, self.INTER_CH_GAP


class ScottieS2(ScottieS1):
    VIS_CODE = 0x38
    SCAN = 88.064 - ScottieS1.INTER_CH_GAP
    WIDTH = 160


class Robot36(ColorSSTV):
    VIS_CODE = 0x08
    WIDTH = 320
    HEIGHT = 240
    SYNC = 9
    INTER_CH_GAP = 4.5
    Y_SCAN = 88
    C_SCAN = 44
    PORCH = 1.5
    SYNC_PORCH = 3
    INTER_CH_FREQS = [None, FREQ_BLACK, FREQ_WHITE]

    def on_init(self):
        self.yuv = self.image.convert('YCbCr').load()

    def encode_line(self, line):
        pixels = [self.yuv[col, line] for col in xrange(self.WIDTH)]
        channel = (line % 2) + 1
        y_pixel_time = self.Y_SCAN / self.WIDTH
        uv_pixel_time = self.C_SCAN / self.WIDTH
        return chain(
                [(FREQ_BLACK, self.SYNC_PORCH)],
                ((byte_to_freq(p[0]), y_pixel_time) for p in pixels),
                [(self.INTER_CH_FREQS[channel], self.INTER_CH_GAP),
                    (FREQ_VIS_START, self.PORCH)],
                ((byte_to_freq(p[channel]), uv_pixel_time) for p in pixels))
		

class PasokonP3(ColorSSTV):
    """
      [ VIS code or horizontal sync here ]  
      Back porch - 5 time units of black (1500 Hz).    
      Red component - 640 pixels of 1 time unit each.    
      Gap - 5 time units of black.   
      Green component - 640 pixels of 1 time unit each.  
      Gap - 5 time units of black.    
      Blue component - 640 pixels of 1 time unit each.   
      Front porch - 5 time units of black.   
      Horizontal Sync - 25 time units of 1200 Hz.
    """
    TIMEUNIT = 1000/4800. # ms
    COLOR_SEQ = (RED, GREEN, BLUE)
    VIS_CODE = 0x71
    WIDTH = 640
    HEIGHT = 480+16
    SYNC = 25 * TIMEUNIT
    SCAN = WIDTH * TIMEUNIT
    INTER_CH_GAP = 5 * TIMEUNIT
    
    def before_channel(self, index):
        if index == self.COLOR_SEQ[0]:
            yield FREQ_BLACK, self.INTER_CH_GAP

    def after_channel(self, index):
        yield FREQ_BLACK, self.INTER_CH_GAP
        
        
class PasokonP5(PasokonP3):
    TIMEUNIT = 1000/3200. # ms
    VIS_CODE = 0x72
    SYNC = 25 * TIMEUNIT
    SCAN = PasokonP3.WIDTH * TIMEUNIT
    INTER_CH_GAP = 5 * TIMEUNIT
        
class PasokonP7(PasokonP3):
    TIMEUNIT = 1000/2400. # ms
    VIS_CODE = 0xF3
    SYNC = 25 * TIMEUNIT
    SCAN = PasokonP3.WIDTH * TIMEUNIT
    INTER_CH_GAP = 5 * TIMEUNIT


MODES = (MartinM1, MartinM2, ScottieS1, ScottieS2, Robot36, PasokonP3, PasokonP5, PasokonP7)
{'fraction_non_alphanumeric': 0.08793573375412422, 'fraction_numerical': 0.03973604934729594, 'mean_word_length': 2.1893870082342177, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '456708', 'n_tokens_mistral': 2773, 'n_tokens_neox': 2437, 'n_words': 607}