From f02f43e4b5ad54b1eceb4b8587a011379e6f3c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Mon, 22 Feb 2016 15:02:00 +0100 Subject: [PATCH] added experimental C code generator --- pysstv/examples/codegen.py | 109 +++++++++++++++++++++++++++++++++++++ pysstv/examples/codeman.c | 28 ++++++++++ 2 files changed, 137 insertions(+) create mode 100644 pysstv/examples/codegen.py create mode 100644 pysstv/examples/codeman.c diff --git a/pysstv/examples/codegen.py b/pysstv/examples/codegen.py new file mode 100644 index 0000000..9063175 --- /dev/null +++ b/pysstv/examples/codegen.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python + +class Image(object): + def __init__(self, content): + self.content = content + + def load(self): + return self + + def __getitem__(self, item): + if isinstance(item, tuple): + x, y = item + return Image('{0}[(ROW({1}) + COL({2})) * 3'.format(self.content, y, x)) + elif isinstance(item, int): + return Image('{0} + RGB({1})]'.format(self.content, item)) + else: + raise NotImplemented + + def __rmul__(self, n): + return Image('({1} * {0})'.format(self.content, float(n))) + + def __mul__(self, n): + return Image('({0} * {1})'.format(self.content, float(n))) + + def __rtruediv__(self, n): + return Image('({1} / {0})'.format(self.content, n)) + + def __truediv__(self, n): + return Image('({0} / {1})'.format(self.content, n)) + + def __radd__(self, n): + return Image('({1} + {0})'.format(self.content, n)) + + def __add__(self, n): + return Image('({0} + {1})'.format(self.content, n)) + + def __str__(self): + return self.content + +from pysstv.color import MartinM1 +import re + +ROW_RE = re.compile(r'ROW\(\d+\)') + +def main(): + sstv = MartinM1(Image('img'), 44100, 16) + n = 0 + print '#define ROW(x) x' + print '#define COL(x) x' + print '#define RGB(x) (2 - (x))' + print 'void convert(unsigned char *img, float *freqs, float *msecs) {\nint frq = 0;' + history = [] + lut = {} + same_as = {} + for freq, msec in sstv.gen_freq_bits(): + printed = 'freqs[frq] = {1}; msecs[frq++] = {2};'.format(n, freq, msec) + key = ROW_RE.sub('row', printed) + old = lut.get(key) + if old is not None: + same_as[n] = old + else: + lut[key] = n + history.append((printed, key)) + n += 1 + del lut + mgen = iter(gen_matches(same_as, history, n)) + m_start, m_len, m_end = next(mgen) + for i in xrange(same_as[m_start]): + print history[i][0] + print 'for (int row = {0}; row >= 0; row -= {1}) {{'.format( + (sstv.HEIGHT - 1) * sstv.WIDTH, sstv.WIDTH) + for i in xrange(same_as[m_start], same_as[m_start] + m_len - 1): + print ' ', history[i][1] + print '}' + print '}}\n\n#define FREQ_COUNT {0}'.format(n) + + + +def gen_matches(same_as, history, n): + cur_start = None + cur_len = None + cur_end = None + matches = [] + for i in xrange(n): + if cur_start is None: + tmp = same_as.get(i) + if tmp is not None: + cur_len = 1 + cur_start = i + cur_end = tmp + else: + tmp = same_as.get(i) + if tmp is not None and history[tmp][1] == history[cur_end + 1][1] and cur_start > cur_end: + cur_len += 1 + cur_end += 1 + else: + if tmp is not None and history[tmp][1] == history[cur_end + 1][1]: + yield cur_start, cur_len, cur_end + tmp = same_as.get(i) + if tmp is None: + cur_start = None + else: + cur_len = 1 + cur_start = i + cur_end = tmp + + +if __name__ == '__main__': + main() diff --git a/pysstv/examples/codeman.c b/pysstv/examples/codeman.c new file mode 100644 index 0000000..fde06a5 --- /dev/null +++ b/pysstv/examples/codeman.c @@ -0,0 +1,28 @@ +#include +#include + +#include "codegen.c" + +void main() { + uint32_t offset, size; + FILE *f = fopen("320x256rgb.bmp", "r"); + fseek(f, 0x02, SEEK_SET); + fread(&size, 4, 1, f); + fseek(f, 0x0A, SEEK_SET); + fread(&offset, 4, 1, f); + fseek(f, offset, SEEK_SET); + + unsigned char img[size]; + + fread(img, size - offset, 1, f); + fclose(f); + + float freqs[FREQ_COUNT], msecs[FREQ_COUNT]; + + convert(img, freqs, msecs); + + for (int i = 0; i < FREQ_COUNT; i++) { + fwrite(&(freqs[i]), 4, 1, stdout); + fwrite(&(msecs[i]), 4, 1, stdout); + } +}