From f7e24de324f57165f7e807d51f30d877e1577267 Mon Sep 17 00:00:00 2001 From: girst Date: Mon, 1 Jul 2019 22:49:26 +0200 Subject: [PATCH] publish (privately developed) version 2 this version has been cooking for quite a while; this commit imports the necessary files to run a basic ttxdv2. reason for the private development (and missing history): I've neglected to commit any changes until now. --- ORFText.cgi | 33 ---- ORFText.pm | 331 +++++++++++++++++++++++++++++++++ channels.conf | 54 ------ html.pl | 93 --------- index.cgi | 244 ++++++++++++++++++++++++ install.sh | 2 - serv.sh | 7 +- src/vtx2ascii-src/Makefile | 17 -- src/vtx2ascii-src/README | 24 --- src/vtx2ascii-src/cct.h | 38 ---- src/vtx2ascii-src/fileio.c | 163 ---------------- src/vtx2ascii-src/fileio.h | 47 ----- src/vtx2ascii-src/main.c | 160 ---------------- src/vtx2ascii-src/misc.h | 41 ---- src/vtx2ascii-src/sys/vtx.h | 151 --------------- src/vtx2ascii-src/vtx.cgi | 140 -------------- src/vtx2ascii-src/vtx_assert.h | 46 ----- src/vtx2ascii-src/vtxdecode.c | 210 --------------------- src/vtx2ascii-src/vtxdecode.h | 45 ----- src/vtx2ascii-src/vtxtools.c | 140 -------------- src/vtx2ascii-src/vtxtools.h | 23 --- 21 files changed, 578 insertions(+), 1431 deletions(-) delete mode 100755 ORFText.cgi create mode 100644 ORFText.pm delete mode 100644 channels.conf delete mode 100755 html.pl create mode 100755 index.cgi delete mode 100644 src/vtx2ascii-src/Makefile delete mode 100644 src/vtx2ascii-src/README delete mode 100644 src/vtx2ascii-src/cct.h delete mode 100644 src/vtx2ascii-src/fileio.c delete mode 100644 src/vtx2ascii-src/fileio.h delete mode 100644 src/vtx2ascii-src/main.c delete mode 100644 src/vtx2ascii-src/misc.h delete mode 100644 src/vtx2ascii-src/sys/vtx.h delete mode 100755 src/vtx2ascii-src/vtx.cgi delete mode 100644 src/vtx2ascii-src/vtx_assert.h delete mode 100644 src/vtx2ascii-src/vtxdecode.c delete mode 100644 src/vtx2ascii-src/vtxdecode.h delete mode 100644 src/vtx2ascii-src/vtxtools.c delete mode 100644 src/vtx2ascii-src/vtxtools.h diff --git a/ORFText.cgi b/ORFText.cgi deleted file mode 100755 index 144b5a2..0000000 --- a/ORFText.cgi +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/perl -X - -use strict; -use warnings; -use 5.010; - -my @pages = (101, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 127, 128, 129, 130, 131, 132, 133, 134, 102, 136, 137, 138, 139, 140, 141, 142, 143, 706, 108, 461, 462, 463, 464, 465); - -print "Content-type: text/html\n\n"; - -print "ORFText News"; -print "

ORFText News

"; -print 'pol | loc [T] | web'; - -foreach (@pages) { - if ($_ == 101) { - print "

Politik

"; - } elsif ($_ == 102) { - print "

Chronik

"; - } elsif ($_ == 706) { - print "

Tirol

"; - } elsif ($_ == 108) { - print "

Web/Media

"; - } - my @subpages = glob "/run/ttxd/spool/2/${_}_*.vtx"; - foreach (@subpages) { - my $file_age = time() - (stat ($_))[9]; - print `./html.pl $_` if $file_age < 1000; - #print "
  • $_ : $file_age
  • " if $file_age > 1000; - } - #print `./html.pl /run/ttxd/spool/2/${_}_00.vtx` if -e "/run/ttxd/spool/2/${_}_00.vtx"; -} -print ""; diff --git a/ORFText.pm b/ORFText.pm new file mode 100644 index 0000000..80879eb --- /dev/null +++ b/ORFText.pm @@ -0,0 +1,331 @@ +package ORFText; +our $VERSION = '2.00'; + +=pod Project: ORFText.pm + - NOW: a module returning data structure with inline-html + - LATER: instead of returning html return a syntax tree + html tag insertion is limited to {{{text mangling}}} + - html_escape # HTML + - emphasize # HTML + - rehyphenate # UNICODE + - linebreak # HTML + - $ORF_idio_slash (negative lookahead against ) + + TODO - URL references (">>tirol.ORF.at") + (C) 2016-2019 Tobias Girstmair + Extracts hypertext formatted news from ORF Teletext + reads and decodes pages from dvbtext's spool directory. +=cut + +use 5.010; +use strict; +use warnings; +use utf8; +use Data::Dumper; + +use base 'Exporter'; +our @EXPORT = qw(html weather $TABLE_YES $REF_MARKUP); +our $TABLE_YES = 0; # enable that to parse tables w/ vtx2ascii +our $REF_MARKUP = sub { return "$_[0]$_[1]"}; + +### i/o {{{ +use constant { + VTX_HEADER => 12, + TTX_HEADER => 8, + STATUS_BAR => 32, +}; +sub slurp_lines { my ($file) = @_; + open VTX, "<:raw", "$file" or die ("Can'r open $file"); + + # read page number: + seek VTX, VTX_HEADER+TTX_HEADER, 0; + read VTX, my $pagenum, 3; + $pagenum &= "\x7f" x 3; # zero out parity bit + + # read page content: + seek VTX, VTX_HEADER+TTX_HEADER+STATUS_BAR, 0; + read VTX, my $raw_text, 40*23; + $raw_text &= ("\x7f" x length $raw_text); # zero out parity bit + # NOTE: unpack chomps strings when using the 'A' template. + my @lines = map {tr/[\\]{|}~`@/ÄÖÜäöüß°§/r} unpack 'A40'x23, $raw_text; + + close VTX; + my ($subpage) = $file=~m/\d{3}_(\d{2})\.vtx/; + return ($pagenum, $subpage, @lines); +} +### }}} +### Teletext Grammar {{{ +# control characters defined in ETSI EN 300 706 (2003) 12.2 Table 26 +my $ORF_TTX_GRAMMAR = qr { +(?(DEFINE) + (? + (?>(?&a_color)) | (?>(?&g_color)) + | (?>(?&flash)) | (?>(?&steady)) + | (?>(?&endbox)) | (?>(?&startbox)) + | (?>(?&n_size)) | (?>(?&d_height)) + | (?>(?&d_width)) | (?>(?&d_size)) + | (?>(?&conceal)) | (?>(?&esc)) + | (?>(?&g_cont)) | (?>(?&g_sep)) + | (?>(?&bg_black)) | (?>(?&bg_new)) + | (?>(?&g_hold)) | (?>(?&g_release)) + | (?>(?&fake)) + ) + (? + (?>(?&a_blk)) + | (?>(?&a_red)) + | (?>(?&a_grn)) + | (?>(?&a_ylw)) + | (?>(?&a_blu)) + | (?>(?&a_mgt)) + | (?>(?&a_cya)) + | (?>(?&a_wht)) + ) + (? + (?>(?&g_blk)) + | (?>(?&g_red)) + | (?>(?&g_grn)) + | (?>(?&g_ylw)) + | (?>(?&g_blu)) + | (?>(?&g_mgt)) + | (?>(?&g_cya)) + | (?>(?&g_wht)) + ) + (? \x00) (? \x10) (? (?&a_blk)|(?&g_blk)) + (? \x01) (? \x11) (? (?&a_red)|(?&g_red)) + (? \x02) (? \x12) (? (?&a_grn)|(?&g_grn)) + (? \x03) (? \x13) (? (?&a_ylw)|(?&g_ylw)) + (? \x04) (? \x14) (? (?&a_blu)|(?&g_blu)) + (? \x05) (? \x15) (? (?&a_mgt)|(?&g_mgt)) + (? \x06) (? \x16) (? (?&a_cya)|(?&g_cya)) + (? \x07) (? \x17) (? (?&a_wht)|(?&g_wht)) + (? \x08) (? \x09) + (? \x0a) (? \x0b) + (? \x0c) (? \x0d) + (? \x0e) (? \x0f) + (? \x18) + (? \x19) (? \x1a) + (? \x1b) # switch G0 charset + (? \x1c) (? \x1d) + (? \x1e) (? \x1f) + + (? (?&cntrl)|[ ]) + (?<_> (?&ws)*) + (? (?&a_wht)|(?&g_wht)|[ ]) + (? \A ^(?&_)) + (? (?&_)$ \Z) + + # graphics characters: + (? \x2c) # middle row (sixel 2^3 and 2^4) + + # fake ctrlchar to mark up subheadings with emphasize(): + (? \x7f) +) +}xms; +# ORF Specific Shortcuts: +# a. page parsing: +my $ORF_10x_title = qr/(?&S)(?&WHT)(?&bg_new)((?&a_red)(?&_)[^\x00]+?)(?&E)$ORF_TTX_GRAMMAR/; +my $ORF_10x_text_1 = qr/(?&S)(?&WHT)(?&bg_new)[^\x01](.+?)(?&E)$ORF_TTX_GRAMMAR/; # text variant 1: non-emph. beginning +my $ORF_10x_text_2 = qr/(?&S)(?&WHT)(?&bg_new)((?&a_red).*(?&a_blk).*)(?&E)$ORF_TTX_GRAMMAR/; # text variant 2: non-whole-line-emph. at beginning +my $ORF_10x_text = qr/(?|$ORF_10x_text_1|$ORF_10x_text_2)/; # combine with "branch reset" pattern +my $ORF_11x_title = qr/(?&S)((?&a_cya)[^\x07]+?)(?&E)$ORF_TTX_GRAMMAR/; +my $ORF_11x_subtitle = qr/^(?&a_ylw)([^\x07]+?)(?&E)$ORF_TTX_GRAMMAR/; # yellow subheadings (not inline-yellow) +my $ORF_11x_text_1 = qr/^(?&WHT)([^\x1d].+)(?&E)$ORF_TTX_GRAMMAR/; # text variant 1: starts with non-emphasised word (\x1d: don't match subres_2) +my $ORF_11x_text_2 = qr/^((?&a_cya).*(?&a_wht).*)(?&E)$ORF_TTX_GRAMMAR/; # text variant 2: starts with non-full-length emphasis +my $ORF_11x_text_3 = qr/^(?&g_red)(?&g_34)+((?&a_cya).+?)(?:(?&g_red)(?&g_34)+|$)$ORF_TTX_GRAMMAR/; # text variant 3: very last line (red band below 11x pages) +my $ORF_11x_text_xtra= qr/^((?:(?&a_ylw)|(?&a_grn)).*(?:(?&a_wht).*)?)(?&E)$ORF_TTX_GRAMMAR/; # hardly used; sort of paragraph heading (->121-20190526-greentext.vtx) +my $ORF_11x_text = qr/(?|$ORF_11x_text_1|$ORF_11x_text_2|$ORF_11x_text_3)/; # combines the regexes above into a single match group; (?|) resets the backref-number +my $ORF_70x_subres = qr/(?&S)(?&a_wht)(?&bg_new)(?&a_red)(?&_)(.+)(?&_)(?&bg_black)(?&E)$ORF_TTX_GRAMMAR/; +my $ORF_subressort = qr/(?&S)(.*?)(?&E)$ORF_TTX_GRAMMAR/; +my $ORF_ressort_topic= qr/(?&S)(?&a_wht)(?&_)(.+?)(?&_)(?&bg_new)(?&_)(.*?)(?&_)(?&bg_black)?(?&E)$ORF_TTX_GRAMMAR/; # topic=fallback title +my $ORF_emptyline = qr/^(?&ws)*$ORF_TTX_GRAMMAR$/; +my $ORF_advert = qr/^[\001\002\004](?&bg_new)(?:[\000\001\007](?!(?&cntrl))|[\003\a]\r|\r\0)(?&_)(.+)(?&_)$ORF_TTX_GRAMMAR/; +# b. reference and emphasis matching: +my $ORF_ref_name_1 = qr/([^\|]*?>+ ?(?:S. ?)?)/; # "Hofer >", "Opposition > S. " +my $ORF_ref_name_2 = qr/(>+[^\|]*?)/; # ">Platter " +my $ORF_ref_name = qr/(?|$ORF_ref_name_1|$ORF_ref_name_2)/; +my $ORF_ref_nums = qr/(\d{3}(?:[-\/]\d{3})?)/; # "113-116", "127/128", "115" +my $ORF_reference = qr/(?:(?&a_red)|(?&a_cya)) *$ORF_ref_name$ORF_ref_nums(?&_)(?:\||$)$ORF_TTX_GRAMMAR/; +my $ORF_10x_emph = qr/(?&a_red)(.*?)(?:(?&a_blk)|(\|)(?! ?(?&a_red))|$)$ORF_TTX_GRAMMAR/; # 10x: red-on-white +my $ORF_11x_emph_y = qr/(?&a_ylw)(.*?)(?:(?&a_wht)|(\|)(?! ?(?&a_ylw))|$)$ORF_TTX_GRAMMAR/; # 11x: yellow-on-black +my $ORF_11x_emph_c = qr/(?&a_cya)(.*?)(?:(?&a_wht)|(\|)(?! ?(?&a_cya))|$)$ORF_TTX_GRAMMAR/; # 11x: cyan-on-black +my $ORF_11x_emph_g = qr/(?&a_grn)(.*?)(?:(?&a_wht)|(\|)(?! ?(?&a_grn))|$)$ORF_TTX_GRAMMAR/; # 11x: green-on-black +my $ORF_emphasis = qr/(?|$ORF_10x_emph|$ORF_11x_emph_y|$ORF_11x_emph_c|$ORF_11x_emph_g)/; +my $ORF_subtitle = qr/(?&fake)(.+?)\|$ORF_TTX_GRAMMAR/; # uses fake ctrlchar to differentiate from yellow-emph +# c. rehyphenation: +my $ORF_hy_ergaenz = qr/(\b\w+\b)-\| ?\b(und|oder)\b ?/; # (Ergänzungsstrich, e.g. "Staats- und Regierungschefs") +my $ORF_hy_trenn = qr/([[:lower:]])-\| ?([[:lower:]])/; # (Trennstrich) +my $ORF_hy_binde = qr/(\S)-\| ?(\S)/; # (Bindestrich, e.g. "Mikl-Leitner", "30-jaehriges", etc.) +my $ORF_hy_gedanken = qr/[ |]-[ |]/; # (Gedankenstrich) +# d. unsave space / idiosyncrasies: +my $ORF_idio_comma = qr/(?|([[:alnum:])"]),([[:alpha:]])|([[:alpha:])"]),([[:alnum:]]))/; # comma: not between 5,4% +my $ORF_idio_period = qr/(?|([[:alnum:])"])\.([[:upper:]])|([[:alpha:])"])\.([[:digit:]]))/; # period: not between 1.000.000, www.foo.org +my $ORF_idio_URL = qr/(\S+)\. (ORF\.at)/; # special case for e.g. tirol.ORF.at +my $ORF_idio_colon = qr/(?|([[:alnum:]]):([[:alpha:]])|([[:alpha:]]):([[:alnum:]]))/; # colon: not between 1:0 +my $ORF_idio_slash = qr/( ?)(?!<)\/( ?)/; # fix foo/bar at end of line ("ÖVP/ FPÖ"->"ÖVP/FPÖ"); negative lookahead to not match from emphasize() +# e. trimming, better-line-breaks, misc.: +my $ORF_ws = qr/(?&ws)$ORF_TTX_GRAMMAR/; # Note: control characters are rendered as whitespace; included as well +my $ORF_is_table = qr/[\x21-\x7e]((?&a_color)|[ ]){2,}[\x21-\x7e]|^\x11\x2c+\x06Liga-Start:$ORF_TTX_GRAMMAR/; # Warn: breaks when line3 is "m/n" -- filter beforehand +my $ORF_bleedover = qr/(.+?) +(.+)/; # when two-line ressort (left-aligned) bleeds into subressort (right-aligned) +# Note: [^\xNN] makes sure each line is only matched by 1 regex +# Note: inline markup is terminated by a ctrlchar (?&a_xxx), linebreak (\|) or end of string ($). +# negative lookahead after \| allows us to match multiline-emphasis in one go +# Note: ORF_hy_* removes linebreaks; have to sanitize lines not ending with a hyphen seperately +# Note: is_table: matches tables by alignment-whitespace; 215-219 have 'Liga-Start' in last line +# }}} +### text mangling {{{ +sub emphasize { for (@_) { + s{$ORF_reference}{ @{[$REF_MARKUP->($1, $2)]} }g; + s{$ORF_subtitle} {

    $1

    }g; + s{$ORF_emphasis} { $1 $2}g; +}} +sub rehyphenate { for (@_) { + use charnames (); + s{$ORF_hy_ergaenz} {$1- $2 }g; + s{$ORF_hy_trenn} {$1\N{SOFT HYPHEN}$2}g; + s{$ORF_hy_binde} {$1-$2}g; + s{$ORF_hy_gedanken}{ \N{EN DASH} }g; +}} +sub linebreak { for (@_) { + s{\|\|+}{

    }g; # mark up paragraphs + s/(

    )+$//gs; # remove if last + s{\| *}{ }g; # remove other line-markers +}} +sub unsave_space { for (@_) { + s{$ORF_idio_comma} {$1, $2}g; + s{$ORF_idio_period}{$1. $2}g; + s{$ORF_idio_colon} {$1: $2}g; + s{$ORF_idio_slash} {$1/$1}g; + s{$ORF_idio_URL} {$1.$2}g; +}} +sub trim_ws { for (@_) { + # Note: also removes cntrl chars + s/^$ORF_ws+|$ORF_ws+$//g; + s/$ORF_ws+/ /g; # keep a space between words +}} +sub html_escape { for (@_) { + s/&/&/g; + s/' or ref.matching breaks! +}} +=pod "Try to infer linebreaks without empty line" + For each line, check if the first word from the next line would fit in the same line + This heuristic is not flawless; ignoring short words helps a lot, but isn't perfect either. + To match each line and the next word (which are overlapping), forward lookahead is used. +=cut +sub better_line_breaks { + return if $_[0] =~ m/\|\|/; # mostly, only cramped pages (i.e. those without any empty lines) need this treatment. + # matches each physical line and the next word: + my @lines = $_[0] =~ m/(?=(?:^|\|)(.*?(?:\||$)[\x00-\x20]*?\w+))/sg; + + my @text = split /\|/, $_[0]; + for (0 .. $#lines) { + $text[$_] .= "|" if (length $lines[$_] < 39 and $lines[$_]=~m/\w{6,}$/); # double up "|" to make empty line + } + $_[0] = join '|', @text; +} +### }}} + +sub html { my ($file) = @_; + my ($title, $text, $subres, $ressort, $topic); + my ($title_2, $text_2, $subres_2); + my $advert; + my $is_table = 0; + + my ($page, $subpage, @lines) = slurp_lines ($file); + + # 1. parse header: + ($subres) = (shift @lines) =~ m{$ORF_subressort}; + ($ressort, $topic) = (shift @lines) =~ m{$ORF_ressort_topic}; + ($ressort, $subres) = ("$1 $ressort", $2) if ($subres =~ m/$ORF_bleedover/); + $subres = $topic if ($page =~ m/70./); # Bundesländer pages + my ($page_x_of_y) = (shift @lines) =~ m{([0-9/]+)}; # will be discarded + + # 2. parse body: + for (@lines) { + if (/$ORF_emptyline/) { + $text .= "|" if defined $text; + } elsif (m{$ORF_is_table} and $page =~/2..|7[56]./) { + return {tabular=>1, raw=>\@lines, title=>$topic,page=>$page,subpage=>$subpage, ressort=>$ressort,subressort=>$subres}; + } elsif ($page < 111) { + if (m{$ORF_10x_title}) { (defined $text?$text:$title) .= "$1|"; } + elsif (m{$ORF_10x_text}) { $text .= "$1|"; } + elsif (m{$ORF_advert}) {$advert .= "$1|" if defined $text;} # WARN: this parses ads + # NOTE: ads only appear after the text; "ads" before it are category pages, which we don't display at all + } elsif ($subres_2) { # second snippet of 70x page + if (m{$ORF_11x_title}) { $title_2 .= "$1|"; } + elsif (m{$ORF_11x_text}) { $text_2 .= "$1|" } + } else { + if (m{$ORF_11x_title}) { (defined $text?$text:$title) .= "$1|"; } + elsif (m{$ORF_11x_subtitle}) { (length $title?$text:$title) .= "\x7f$1|"; } + elsif (m{$ORF_11x_text}) { $text .= "$1|"; } + elsif (m{$ORF_11x_text_xtra}){ $text .= "|$1||"; } + elsif (m{$ORF_70x_subres}) { $subres_2 = $1; } + # TEMP: display other-colored text as normal: + elsif (m{^(?&a_color)$ORF_TTX_GRAMMAR}) {$text.="|{ $_ }|";} + } + + $is_table += !!(defined $text and m{$ORF_is_table}); + } + + # 3. post-processing + if ($topic =~ /\bPresse zum\b/) { + # Pressespiegel: use topic as title; TODO: requires testing + $text = "$title $text"; + $title = $topic; + } else { + # otherwise: only use topic if no title (6xx has neither) + $title //= $topic || "$ressort - $subres"; + } + if ($is_table > 1) { # NOTE: we ignore a 1-off double-spacing mistake (quite common) + $text =~ s/(?&cntrl)$ORF_TTX_GRAMMAR/ /g; # remove all markup/colors + $text =~ s/[|{}]+/||/g; # force new paragraph for each ttx-line + } + better_line_breaks ($text); # tries to guess where a line break should be + + html_escape ($text, $title, $advert//(), $text_2//(), $title_2//()); # HTML + emphasize ($text, $advert//(), $text_2//()); # HTML + trim_ws ($text, $title, $advert//(), $text_2//(), $title_2//()); + rehyphenate ($text, $title, $advert//(), $text_2//(), $title_2//()); # UNICODE + linebreak ($text, $title, $advert//(), $text_2//(), $title_2//()); # HTML + unsave_space($text, $title, $advert//(), $text_2//(), $title_2//()); + + return { + title => $title, + text => $text, + topic => $topic, + page => $page, + subpage => defined $subres_2? 'A': 0+($subpage//0), + ressort => $ressort, + subressort => $subres, + advert => $advert, + }, defined $subres_2? { + title => $title_2, + text => $text_2, + topic => "", + page => $page, + subpage => 'B', + ressort => $ressort, + subressort => $subres_2, + }: undef; +} + +sub weather { my ($spool, $city) = @_; + my $s = qr{[\x00-\x20]+}; + my $S = qr{[^\x00-\x20]+?}; + my %weather; + for (<$spool/601_01.vtx $spool/6{0[2-9],10}_??.vtx>) { + my ($page, $subpage, @lines) = slurp_lines ($_); + for (grep /${s}$city/, @lines) { + my ($loc, $time, $wetter, $temp) = + m/$s(.*?)$s($S)h$s(.*?)$s([-0-9,°]+)$s?/; + + $weather{time} = "$time:00"; + $weather{location} = $loc; + $weather{weather} = $wetter; + $weather{temperature} = $temp; + return %weather if $temp; + } + } + return undef; +}; +1; # vim:foldmethod=marker diff --git a/channels.conf b/channels.conf deleted file mode 100644 index 15e3d75..0000000 --- a/channels.conf +++ /dev/null @@ -1,54 +0,0 @@ -#Name:Frequency:Parameters:Source:SRate:VPID:APID:TPID:CA:SID:NID:TID:RID -ZDF HD;ORF:506000:B8G16S1T32P1:T:27500:7010=27:0;7011,7012:7015:69C:14701:8232:701:0 -Das Erste HD;ORF:506000:B8G16S1T32P1:T:27500:7020=27:0;7021,7022:7025:69C:14702:8232:701:0 -ZDFneo HD;ORF:506000:B8G16S1T32P1:T:27500:7030=27:0;7031,7032:7035:69C:14703:8232:701:0 -Eurosport 1;ORF:506000:B8G16S1T32P1:T:27500:7040=27:0;7041:7045:69C:14704:8232:701:0 -Sport 1;ORF:506000:B8G16S1T32P1:T:27500:7050=27:0;7051:7055:69C:14705:8232:701:0 -kabel eins;ORF:506000:B8G16S1T32P1:T:27500:7060=27:0;7061:7065:69C:14706:8232:701:0 -RTL II;ORF:506000:B8G16S1T32P1:T:27500:7070=27:0;7071:7075:69C:14707:8232:701:0 -sixx;ORF:506000:B8G16S1T32P1:T:27500:7080=27:0;7081:7085:69C:14708:8232:701:0 -Playboy TV;ORF:506000:B8G16S1T32P1:T:27500:7090=27:0;7091:0:69C:14709:8232:701:0 -KiKA;ORF:506000:B8G16S1T32P1:T:27500:7100=27:0;7101:7105:69C:14710:8232:701:0 -ATV HD;ATV:530000:B8G32S1T8P0:T:27500:5010=27:0;5011:5015:69C:14501:8232:501:0 -PULS 4;sevenonemedia:530000:B8G32S1T8P0:T:27500:5020=27:0;5021:5025:69C:14502:8232:501:0 -ServusTV HD;ServusTV:530000:B8G32S1T8P0:T:27500:5030=27:0;5031,5032:5035:69C:14503:8232:501:0 -RTL HD;RTL:530000:B8G32S1T8P0:T:27500:5040=27:0;5041:5045:69C:14504:8232:501:0 -3sat HD;3SAT:530000:B8G32S1T8P0:T:27500:5050=27:0;5051,5052:5055:69C:14505:8232:501:0 -SRFzwei HD;-:530000:B8G32S1T8P0:T:27500:5060=27:0;5061:5065:69C:14506:8232:501:0 -SRF 1 ;-:530000:B8G32S1T8P0:T:27500:5070=27:0;5071:5075:69C:14507:8232:501:0 -ATV 2;ATV:530000:B8G32S1T8P0:T:27500:5080=27:0;5081:5085:0:14508:8232:501:0 -Flimmit Zusatzpaket;ORS:530000:B8G32S1T8P0:T:27500:5090=27:0:0:0:14509:8232:501:0 -ATVsmart;ATV:530000:B8G32S1T8P0:T:27500:5100=27:0:0:0:14510:8232:501:0 -ProSieben HD;ORF:570000:B8G16S1T32P1:T:27500:8010=27:0;8011:8015:69C:14801:8232:801:0 -PULS 4 HD;ORF:570000:B8G16S1T32P1:T:27500:8020=27:0;8021:8025:69C:14802:8232:801:0 -SAT.1 HD;ORF:570000:B8G16S1T32P1:T:27500:8030=27:0;8031:8035:69C:14803:8232:801:0 -VOX HD;ORF:570000:B8G16S1T32P1:T:27500:8040=27:0;8041:8045:69C:14804:8232:801:0 -ATV;ORF:570000:B8G16S1T32P1:T:27500:8050=27:0;8051:8055:0:14805:8232:801:0 -4News;ORS:570000:B8G16S1T32P1:T:27500:8060=27:0:0:0:14806:8232:801:0 -Disney Channel;ORF:570000:B8G16S1T32P1:T:27500:8070=27:0;8071:8075:69C:14807:8232:801:0 -Deluxe Music;ORF:570000:B8G16S1T32P1:T:27500:8080=27:0;8081:0:69C:14808:8232:801:0 -CNN;ORF:570000:B8G16S1T32P1:T:27500:8090=27:0;8091:0:69C:14809:8232:801:0 -Radio Maria;ORF:570000:B8G16S1T32P1:T:27500:0:0;8111:0:0:14811:8232:801:0 -Kronehit;-:570000:B8G16S1T32P1:T:27500:0:0;8112:0:69C:14812:8232:801:0 -RADIO OE24;-:570000:B8G16S1T32P1:T:27500:0:0;8113:0:0:14813:8232:801:0 -ARTE HD;ORS:586000:B8G16S1T32P1:T:27500:6010=27:0;6011,6012:6015:69C:14601:8232:601:0 -BR Fernsehen Sued HD;ORS:586000:B8G16S1T32P1:T:27500:6020=27:0;6021,6022:6025:69C:14602:8232:601:0 -Nickelodeon;ORS:586000:B8G16S1T32P1:T:27500:6030=27:0;6031:0:69C:14603:8232:601:0 -RTL NITRO;ORS:586000:B8G16S1T32P1:T:27500:6040=27:0;6041:6045:69C:14604:8232:601:0 -SUPER RTL;ORS:586000:B8G16S1T32P1:T:27500:6050=27:0;6051:6055:69C:14605:8232:601:0 -SAT.1 Gold;ORS:586000:B8G16S1T32P1:T:27500:6060=27:0;6061:6065:69C:14606:8232:601:0 -DMAX;ORS:586000:B8G16S1T32P1:T:27500:6070=27:0;6071:6075:69C:14607:8232:601:0 -PHOENIX;ORS:586000:B8G16S1T32P1:T:27500:6080=27:0;6081:6085:69C:14608:8232:601:0 -n-tv;ORS:586000:B8G16S1T32P1:T:27500:6090=27:0;6091:6095:69C:14609:8232:601:0 -ORF1 HD;ORF:634000:B8S1P0:T:27500:4010=27:0;4011,4012:4015:69C:14401:8232:401:0 -ORF2 T HD;ORF:634000:B8S1P0:T:27500:4000=27:0;4001,4002:4005:69C:14402:8232:401:0 -ORF2 V HD;ORF:634000:B8S1P0:T:27500:4000=27:0;4001,4002:4005:69C:14403:8232:401:0 -ORF III HD;ORF:634000:B8S1P0:T:27500:4050=27:0;4051,4052:4055:69C:14405:8232:401:0 -ORF Sport+ HD;ORF:634000:B8S1P0:T:27500:4060=27:0;4061,4062:4065:69C:14406:8232:401:0 -ORF1;ORF:634000:B8S1P0:T:27500:4070=27:0;4071:4015:0:14407:8232:401:0 -ORF2 W;ORF:634000:B8S1P0:T:27500:4080=27:0;4081:4005:0:14408:8232:401:0 -3-Visual-Radio;ORF:634000:B8S1P0:T:27500:4150=27:0;4130:0:0:14415:8232:401:0 -ORF2 K HD;ORF:634000:B8S1P0:T:27500:4000=27:0;4001,4002:4005:69C:14404:8232:401:0 -Radio sterreich 1;ORF:634000:B8S1P0:T:27500:0:0;4090:0:0:14409:8232:401:0 -Hitradio 3;ORF:634000:B8S1P0:T:27500:0:0;4130:0:0:14413:8232:401:0 -radio FM4;ORF:634000:B8S1P0:T:27500:0:0;4140:0:0:14414:8232:401:0 diff --git a/html.pl b/html.pl deleted file mode 100755 index d799f44..0000000 --- a/html.pl +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/perl -X - -# (C) 2016-2017 Tobias Girstmair -# Extracts hypertext formatted news from ORF Teletext -# uses a modified version of vtx2ascii to decode pages -# from dvbtext's spool directory. - -# Usage: ./plain.pl -# Output: HTML - -use strict; -use warnings; -use 5.010; -# convert to utf-8 before outputting; WARN: still processes latin-1 (regexes too)! -binmode STDOUT, ":encoding(utf8)"; - -my %meta; -my $title; -my $text = ""; -my $page = shift; -my ($subpage) = $page=~m/\d{3}_(\d{2})/; #requires ppp_ss file name scheme! @parens: https://stackoverflow.com/a/10034105 -$subpage += 0; # convert to number to remove leading zero -# run through vtx2ascii (has been modified to output correct ISO 8859-1 without national replacements) -open (VTX, "./vtx2ascii -a $page |") || die ("Can'r run vtx2ascii"); -my $last = ""; -my $is_10x = 0; -do { - # transliterate from ETSI EN 300 706 G0 German to latin-1 (AOUaouBoS): - tr/[\\]{|}~`@/\N{U+C4}\N{U+D6}\N{U+DC}\N{U+E4}\N{U+F6}\N{U+FC}\N{U+DF}\N{U+B0}\N{U+A7}/; - my $line = $_; - $line =~ s/^\s+|\s+$//g; - chomp ($line); - - given ($.) { - when (1) { %meta = parse_metadata ($line) ; $is_10x = ($meta{'page'}<110) } - when (2) { $meta{'subres'} = $line } - when (3) { $meta{'res'} = $line } - when (4) {} - when (5 + (1*$is_10x)) { $title = $line } - when (4 + (1*$is_10x)) {} - when (4 + (3*$is_10x)) { $title .=$line if ($title eq "")} - default { $text .= $last . "_EOL_" . ($last eq ""?"":($line eq ""?"
    ":" ")) } - } - $last = $line unless $. == (5+(2*$is_10x)); -} while (); -$text .= $last; - -# substitute hyphenation: -# * replace with soft hyphen when it splits a word (between lowercase letters; -# still allows line break when necessary. -# * keep, when followed by uppercase letter (e.g. "PIN-Nummer") -# * keep, when after a digit (e.g "30-jaehriges") -# * remove in any other case (was: forced hyphenation due to space constraints) -# ad _EOL_: linebreaks already stripped in loop above; wouldn't work either way -# due to single line regex. INFO: Underscore is in DE-localized teletext charset. -# ad s/und/UND/: otherwise, "foo- und barbaz" will become "foound barbaz" -$text =~ s/\bund\b/_UND_/g; -$text =~ s/([[:lower:]])-_EOL_ ([[:lower:]])/\1­\2/g; -$text =~ s/([[:alnum:]])-_EOL_ ([[:upper:]])/\1-\2/g; -$text =~ s/([[:digit:]])-_EOL_ ([[:alnum:]])/\1-\2/g; -$text =~ s/_UND_/und/g; -$text =~ s/_EOL_//g; - -# remove ORFText idiosyncrasies -$text =~ s/([[:alnum:]]),([[:alpha:]])/\1, \2/g; # no space after comma to save space... -$text =~ s/([[:alpha:]]),([[:alnum:]])/\1, \2/g; # ...but not between numbers -$text =~ s/([[:alnum:]])\.([[:upper:]])/\1. \2/g; # no space after period to save space... (WARN: breaks URLS like tirol.ORF.at) -$text =~ s/([[:alpha:]])\.([[:upper:][:digit:]])/\1. \2/g; # ...but not between numbers -$text =~ s/([[:alnum:]]):([[:alnum:]])/\1: \2/g; # no space after colon to save space... TODO: doesn't work - -# adblocker: (keep it 7bit-ASCII; perl processes latin1, but this script is utf-8 encoded (output will be utf8 due to `binmode` at beginning)) -$text =~ s/Kalendarium - t.glich neu \. 734//g; -$text =~ s/>>tirol\. ?ORF\.at//g; - -my @tmp = split(' ',$meta{'date'}); -my $shortdate = substr $tmp[1], 0, 6; -my $pagesubpage = $meta{'page'} . ($subpage > 0?".$subpage":""); -my $moreinfo = "$meta{'res'} - $meta{'subres'}; $meta{'date'}"; -print "

    $pagesubpage: $title
    $text

    "; - -close (VTX); - -sub parse_metadata { - my @elems = split ' ', @_[0]; - - my %retval = ( - 'page' => shift @elems, - 'channel' => shift @elems, - 'date' => join (' ', @elems) - ); - - return %retval; -} diff --git a/index.cgi b/index.cgi new file mode 100755 index 0000000..888fa9c --- /dev/null +++ b/index.cgi @@ -0,0 +1,244 @@ +#!/usr/bin/perl -X +# vim: foldmethod=marker + +use strict; +use warnings; +use 5.010; +use utf8;use open qw/:std :utf8/; + +use ORFText; + +=pod +TODO: %headings won't register when topstory is missing (->sportarten) +this is version 2.0 of ttxd +values for query string/cookie: + - special flags start with _ + - _noqna: hide "fragen/antworten" (set by default) + - numeric: pagenumbers +=cut + +my $pages = $ENV{HTTP_COOKIE} // join '&', ( + 101, 113 .. 125, # Politik: Österreich/EU + 127 .. 134, # Politik: International + 102,#136 .. 144, # Chronik +# 701 .. 709 # Bundesländer (W-NÖ-B-OÖ-S-T-V-K-St) +# 471 .. 478 # Nachrichten leicht verständlich +# 103, 146 .. 149 # Leute +# 104, 151 .. 159 # Wirtschaft +# 161,167,169, # Börse +# 170,172,174 # -"- +# 105, 203 .. 209, # Sport vom Tag +# 210 .. 259, # Sportarten +# 261 .. 278, # Wintersport & Großereignisse +# 107,110,191..198, # Show und Kultur + 108,#461 .. 465, # Web/Media +# 468 .. 469, # Webtipps +# Special Flags: + "_noqna", # hide Q-and-A +); + +my @pages = split /&/, ($ENV{QUERY_STRING} =~ s/(\d{3})-(\d{3})/${\join'&',$1..$2}/gr) // $pages; + +# pages from query string won't affect cookie +#print "Set-Cookie: $pages; Max-Age=2147483647\r\n"; +print "Content-type: text/html\r\n\r\n"; + +# html format {{{ +$ORFText::REF_MARKUP = sub { + return qq{$_[0]$_[1]} +}; +sub format_table { + my $text = join("\n",map{s/[\x00-\x20]/ /gr}@{%{$_[0]}{raw}})=~s/^ ,,+//msr=~s/\n+$//r; + return {%$_, text=>"
    $text
    "}; +} +sub format_html { my %page = %{$_[0] or return}; + no warnings 'numeric'; + use List::Util qw[max]; + sub ifdef { $_[1]? "$_[0]$_[1]":"" } + my $pagespec = substr($page{page},0,1) ."00/$page{page}_000".max($page{subpage},1); + + return <<"HTML"; +
    +

    + $page{page}${\ifdef('.',$page{subpage})}: + $page{title} +

    +

    $page{text} + +

    +
    +HTML +} +# }}} +# headings {{{ +my %headings = ( + 101 => "Politik: Österreich/EU", + 127 => "Politik: International", + 102 => "Chronik", + 103 => "Leute", + 104 => "Wirtschaft", + 161 => "Börse", + 105 => "Sport", + #203 => "Sport vom Tag", + #260 => "Wintersport und Großereignisse" + 106 => "Fernsehen", + 108 => "Multimedia", + 107 => "Kultur & Show", # XXX: this will show it multiple times! + 110 => "Kultur & Show", + 109 => "Wetter", + 471 => "Nachrichten leicht verständlich", + 481 => "Nachrichten leichter verständlich", + 701 => "Wien", + 702 => "Niederösterreich", + 703 => "Burgenland", + 704 => "Oberösterreich", + 705 => "Salzburg", + 706 => "Tirol", + 707 => "Vorarlberg", + 708 => "Kärnten", + 709 => "Steiermark", + +); +# }}} +# html-head {{{ +print <<'EOF'; + + + + +ORFText News + + + +
    +

    ORFText News

    +EOF +# }}} +my (@all, @nonempty); +page:foreach (grep/[0-9]/,@pages) { + print "

    $headings{$_}

    \n" if $headings{$_}; + + my $pageno = $_; + push @all, $pageno; + foreach (glob "/run/ttxd/spool/2/${_}_*.vtx") { + my $file_age = time - (stat)[9]; + next if $file_age > 300; + + for (ORFText::html($_)) { + next unless $_; # fail req'd for $nonempty + if ("_noqna" ~~ @pages) { # hide Q-and-A + next page if %{$_}{text}=~m@[Aa]lle Fra.?gen/Antworten.+?500@;# /.?/ is a soft hyphen + } + $_ = format_table $_ if %$_{tabular}; + print format_html $_ ; + push @nonempty, $pageno; + } + } +} + +sub subtr { return grep{not%{{map{$_=>1}@{$_[1]}}}{$_}} @{$_[0]}; } +sub uniq { return sort keys %{{@_}}; } +my @empty = uniq subtr [sort @all], [@nonempty]; # WARN: uniq breaks when sort is removed! +my ($N, $n) = ('n'x!!$#empty, 'n'x!!$#all); +print "

    "; +print "Tafel$N @{[join ', ', @empty]} wurde$N nicht gefunden. " if @empty; +print "

    "; + +print ""; +print "
    "; diff --git a/install.sh b/install.sh index 4ebb975..7f73bfc 100644 --- a/install.sh +++ b/install.sh @@ -6,11 +6,9 @@ then echo "must be root" fi sh -c 'cd ./src/dvbtext-src/; make' -sh -c 'cd ./src/vtx2ascii-src/; make' sh -c 'cd ./src/thttpd-2.27/; make' sh -c 'cd ./src/szap-s2/; make' cp ./src/dvbtext-src/dvbtext . -cp ./src/vtx2ascii-src/vtx2ascii . cp ./src/thttpd-2.27/thttpd . cp ./src/szap-s2/tzap-t2 . cp ./ttxd.service /etc/systemd/system/ diff --git a/serv.sh b/serv.sh index 002a68b..883bb78 100755 --- a/serv.sh +++ b/serv.sh @@ -1,13 +1,12 @@ #!/bin/bash -cd /opt/ttxd/ +cd /opt/Misc_HTTPd/ttx/ -killall tzap-t2 dvbtext thttpd +killall tzap-t2 dvbtext mkdir -p /run/ttxd/spool/{1,2,3,4,5,6,7,8} ./tzap-t2 -a0 -f1 -V -c channels.vdr "ORF1;ORF" &>/dev/null& sleep 5 # TODO: detect FE_HAS_LOCK -./dvbtext 4015 4005 & # 4015=ORF1, 4005=ORF2 -./thttpd -p 8080 -d /opt/ttxd/ -c '**.cgi' +./dvbtext 4015 4005 4055 & # ORF1, ORF2, ORF3 diff --git a/src/vtx2ascii-src/Makefile b/src/vtx2ascii-src/Makefile deleted file mode 100644 index 2e44aef..0000000 --- a/src/vtx2ascii-src/Makefile +++ /dev/null @@ -1,17 +0,0 @@ - -CC=gcc -CFLAGS=-Wall -g -O2 -I. - -PROG=vtx2ascii - -$(PROG): main.o fileio.o vtxtools.o vtxdecode.o - $(CC) $(CFLAGS) -o $@ $^ - -clean: - rm -f *.o *~ - -distclean: clean - strip $(PROG) - -realclean: clean - rm -f $(PROG) diff --git a/src/vtx2ascii-src/README b/src/vtx2ascii-src/README deleted file mode 100644 index c3e85bf..0000000 --- a/src/vtx2ascii-src/README +++ /dev/null @@ -1,24 +0,0 @@ - -'make' should build the whole thing. - -vtx2ascii is a simple converter, build out of the videotext sources. -In fact only the main.c is my work, all other C code is just copyed -from the videotext package. Start it without arguments to get help. - -vtx.cgi is a cgi script for converting vtx-pages on-the-fly. Lynx -approved, with netscape 4 (style sheets required) you'll get colors. -Uses vtx2ascii. You have to adjust two config lines at the top of -the script. Usage is very simple, just copy it to your server's -cgi-bin directory and point your browser to it. If you want, you -can hide it with a Alias like this one: - ScriptAlias /videotext /home/www/cgi/vtx.cgi # in srm.conf - -vtx.cgi delivers a correct last-modified header (=> cacheable pages) -for fast browsing. For script hacking you probably want to turn this -off... - -Known issues: can't show hidden text, 8-bit chars don't work (wrong -mapping), probably more. It is'nt tested much, sort of prototype. - - Gerd - diff --git a/src/vtx2ascii-src/cct.h b/src/vtx2ascii-src/cct.h deleted file mode 100644 index 6846771..0000000 --- a/src/vtx2ascii-src/cct.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef CCT_H_INCLUDED -#define CCT_H_INCLUDED - -/* $Id: cct.h,v 1.1 1996/09/22 22:37:43 mb Exp mb $ - * - * Copyright (c) 1994-96 Martin Buck - * Read COPYING for more information - */ - - -#include - - -#define CCTOK 0 -#define CCTNOTFOUND 1 -#define CCTERR -1 -#define CCTEINVAL -2 -#define CCTEOPEN -3 -#define CCTEVERSION -4 -#define CCTENOTOPEN -5 - - -extern char *cct_device; - -int cct_open(int major, int minor, vtx_info_t *prg_info); -void cct_close(void); -int cct_clearpgbuf(int pgbuf); -int cct_checkpage(int pgbuf); -int cct_stop_dau(int pgbuf); -int cct_reset_pgfound(int pgbuf); -int cct_searchpage(int page, int hour, int minute, int pagemask, int pgbuf); -int cct_getpage(int pgbuf, int x1, int y1, int x2, int y2, byte_t *buffer, vtx_pageinfo_t *info); -int cct_putpage(int x1, int y1, int x2, int y2, const byte_t *buffer, const vtx_pageinfo_t *info); -int cct_set_display(vtxdisp_t disp); -int cct_clear_cache(void); -int cct_set_virtual(int virtual); - -#endif /* CCT_H_INCLUDED */ diff --git a/src/vtx2ascii-src/fileio.c b/src/vtx2ascii-src/fileio.c deleted file mode 100644 index 5c59237..0000000 --- a/src/vtx2ascii-src/fileio.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * fileio.c: Read font-bitmaps, write GIF-, PPM-, ASCII- & VTX-files - * - * $Id: fileio.c,v 1.5 1997/08/14 22:59:42 mb Exp mb $ - * - * Copyright (c) 1995-96 Martin Buck - * Read COPYING for more information - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include "vtx_assert.h" -#include "vtxdecode.h" -#include "vtxtools.h" -#include "misc.h" -#include "fileio.h" - -#define VTXFONT_EXT ".vtxfont" -typedef enum { FP_ARG, FP_ENV, FP_DEFAULT } fp_src_t; - - -char *vtx_fontpath; - - -static const int vtx_img_red[8] = { 0, 255, 0, 255, 0, 255, 0, 255 }; -static const int vtx_img_green[8] = { 0, 0, 255, 255, 0, 0, 255, 255 }; -static const int vtx_img_blue[8] = { 0, 0, 0, 0, 255, 255, 255, 255 }; - -static const vtxpage_t *vtxpage; -static const vtxbmfont_t *vtxfont; -static int reveal; - - - -void -export_ascii(FILE *file, const vtxpage_t *page, int show_hidden) { - int pos; - - for (pos = 0; pos < VTX_PAGESIZE; pos++) { - if (!(page->attrib[pos] & VTX_HIDDEN) || show_hidden) { - fputc(vtx2iso_table[page->chr[pos]], file); - } else { - fputc(' ', file); - } - if (pos % 40 == 39) - fputc('\n', file); - } -} - - -void -save_vtx(FILE *file, const byte_t *buffer, const vtx_pageinfo_t *info, int virtual) { - fputs("VTXV4", file); - fputc(info->pagenum & 0xff, file); - fputc(info->pagenum / 0x100, file); - fputc(info->hour & 0xff, file); - fputc(info->minute & 0xff, file); - fputc(info->charset & 0xff, file); - fputc(info->delete << 7 | info->headline << 6 | info->subtitle << 5 | info->supp_header << 4 | - info->update << 3 | info->inter_seq << 2 | info->dis_disp << 1 | info->serial << 0, file); - fputc(info->notfound << 7 | info->pblf << 6 | info->hamming << 5 | (!!virtual) << 4 | - 0 << 3, file); - fwrite(buffer, 1, virtual ? VTX_VIRTUALSIZE : VTX_PAGESIZE, file); -} - - -int -load_vtx(FILE *file, byte_t *buffer, vtx_pageinfo_t *info, int *virtual) { - byte_t tmp_buffer[VTX_VIRTUALSIZE]; - vtx_pageinfo_t tmp_inf; - unsigned char tmpstr[256]; - struct stat st; - int pos, tmpbits, is_virtual = FALSE, is_sevenbit = FALSE; - - memset(tmp_buffer, ' ', sizeof(tmp_buffer)); - if (fscanf(file, "VTXV%c", tmpstr) != 1) { - if (fstat(fileno(file), &st) < 0) { - return LOADERR; - /* The stupid INtv format doesn't use a signature, so we have to use the file-length instead */ - } else if (st.st_size != 1008) { - return LOADEMAGIC; - } - memset(&tmp_inf, 0, sizeof(tmp_inf)); /* Read ITV-file */ - rewind(file); - for (pos = 0; pos <= 23; pos++) { - fseek(file, 2, SEEK_CUR); - fread(tmp_buffer + pos * 40, 40, 1, file); - } - /* The first 8 bytes in the INtv-format usually contain garbage (or data I don't understand) */ - memset(tmp_buffer, vtx_mkparity(' '), 8 * sizeof(byte_t)); - for (pos = 0; pos <= 2; pos++) { - tmpstr[pos] = tmp_buffer[8 + pos]; - vtx_chkparity(&tmpstr[pos]); - } - tmpstr[3] = '\0'; - sscanf(tmpstr, "%3x", &tmp_inf.pagenum); - if (!vtx_chkpgnum(tmp_inf.pagenum, TRUE)) { - tmp_inf.pagenum = 0; - } - if (virtual) { - *virtual = FALSE; - } - } else { - if (tmpstr[0] != '2' && tmpstr[0] != '3' && tmpstr[0] != '4') { - return LOADEVERSION; - } - tmp_inf.pagenum = fgetc(file) + 0x100 * fgetc(file); /* Read VTX-file */ - tmp_inf.hour = fgetc(file); - tmp_inf.minute = fgetc(file); - tmp_inf.charset = fgetc(file); - tmpbits = fgetc(file); - tmp_inf.delete = !!(tmpbits & 0x80); - tmp_inf.headline = !!(tmpbits & 0x40); - tmp_inf.subtitle = !!(tmpbits & 0x20); - tmp_inf.supp_header = !!(tmpbits & 0x10); - tmp_inf.update = !!(tmpbits & 8); - tmp_inf.inter_seq = !!(tmpbits & 4); - tmp_inf.dis_disp = !!(tmpbits & 2); - tmp_inf.serial = (tmpbits & 1); - tmpbits = fgetc(file); - tmp_inf.notfound = !!(tmpbits & 0x80); - tmp_inf.pblf = !!(tmpbits & 0x40); - tmp_inf.hamming = !!(tmpbits & 0x20); - if (tmpstr[0] == '3') { - is_virtual = TRUE; - } else if (tmpstr[0] == '4') { - is_virtual = !!(tmpbits & 0x10); - is_sevenbit = !!(tmpbits & 8); - } - fread(tmp_buffer, is_virtual ? VTX_VIRTUALSIZE : VTX_PAGESIZE, 1, file); - if (virtual) { - *virtual = is_virtual; - } - } - if (feof(file)) { - return LOADECORRUPT; - } - if (ferror(file)) { - return LOADERR; - } - if (buffer) { - /* If file was saved in seven-bit mode, fake parity bit. - * FIXME: Should we add parity to the virtual part too? - */ - if (is_sevenbit) { - for (pos = 0; pos < VTX_PAGESIZE; pos++) { - tmp_buffer[pos] = vtx_mkparity(tmp_buffer[pos]); - } - } - memcpy(buffer, tmp_buffer, is_virtual ? VTX_VIRTUALSIZE : VTX_PAGESIZE); - memset(buffer, vtx_mkparity(7), 8); - } - if (info) { - *info = tmp_inf; - } - return LOADOK; -} diff --git a/src/vtx2ascii-src/fileio.h b/src/vtx2ascii-src/fileio.h deleted file mode 100644 index f2d55a0..0000000 --- a/src/vtx2ascii-src/fileio.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef VTXBITMAP_H_INCLUDED -#define VTXBITMAP_H_INCLUDED - -/* $Id: fileio.h,v 1.3 1997/08/14 23:00:12 mb Exp mb $ - * - * Copyright (c) 1995-96 Martin Buck - * Read COPYING for more information - */ - - -#include -#include "vtxdecode.h" - - -#define BITS_PER_BYTE 8 - -#define LOADOK 0 -#define LOADERR -1 -#define LOADEMAGIC -2 -#define LOADEVERSION -3 -#define LOADECORRUPT -4 - - -typedef struct { - int xsize, ysize, bpr, bpc; - unsigned char *bitmap; -} vtxbmfont_t; - - -extern char *vtx_fontpath; - - -vtxbmfont_t * read_font(unsigned int xsize, unsigned int ysize); -#ifdef GIF_SUPPORT -void export_gif(FILE *file, const vtxpage_t *page, const vtxbmfont_t *font, int interlace, - int show_hidden); -#endif -void export_ppm(FILE *file, const vtxpage_t *page, const vtxbmfont_t *font, int show_hidden); -#ifdef PNG_SUPPORT -int export_png(FILE *file, const vtxpage_t *page, const vtxbmfont_t *font, int interlace, - int show_hidden, char ***msg_list); -#endif -void export_ascii(FILE *file, const vtxpage_t *page, int show_hidden); -void save_vtx(FILE *file, const byte_t *buffer, const vtx_pageinfo_t *info, int virtual); -int load_vtx(FILE *file, byte_t *buffer, vtx_pageinfo_t *info, int *virtual); - -#endif /* VTXBITMAP_H_INCLUDED */ diff --git a/src/vtx2ascii-src/main.c b/src/vtx2ascii-src/main.c deleted file mode 100644 index 2c83864..0000000 --- a/src/vtx2ascii-src/main.c +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "fileio.h" - -unsigned char buffer[65536]; -vtxpage_t page; -int virtual; - -#define OUT_ASCII 1 -#define OUT_ANSI 2 -#define OUT_HTML 3 - -void -export_ansi_ascii(FILE *file, const vtxpage_t *page, int show_hidden) -{ - int pos; - int bg,fg,lbg,lfg,hidden; - - lfg = lbg = -1; - for (pos = 0; pos < VTX_PAGESIZE; pos++) { - fg = page->attrib[pos] & VTX_COLMASK; - bg = (page->attrib[pos] & VTX_BGMASK) >> 3; - hidden = (page->attrib[pos] & VTX_HIDDEN) && !show_hidden; - if (fg != lfg || bg != lbg) { - fprintf(file,"\033[%d;%dm",fg+30,bg+40); - lfg = fg; - lbg = bg; - } - fputc(hidden ? ' ' : vtx2iso_table[page->chr[pos]], file); - if (pos % 40 == 39) { - lfg = lbg = -1; - fprintf(file,"\033[0m\n"); - } - } -} - -void -export_html(FILE *file, const vtxpage_t *page, int show_hidden) -{ - static const char *color[] = { - "black", "red", "green", "yellow", - "blue", "magenta", "cyan", "white" - }; - - int pos; - int bg,fg,lbg,lfg,hidden; - int used[64]; - - /* scan for used colors */ - memset(used,0,sizeof(used)); - for (pos = 0; pos < VTX_PAGESIZE; pos++) { - fg = page->attrib[pos] & VTX_COLMASK; - bg = (page->attrib[pos] & VTX_BGMASK) >> 3; - used[fg*8+bg] = 1; - } - - /* print styles */ - fprintf(file,"\n"); - - /* print page */ - fprintf(file,"
    \n");
    -	lfg = lbg = -1;
    -	for (pos = 0; pos < VTX_PAGESIZE; pos++) {
    -		fg     =  page->attrib[pos] & VTX_COLMASK;
    -		bg     = (page->attrib[pos] & VTX_BGMASK) >> 3;
    -		hidden = (page->attrib[pos] & VTX_HIDDEN) && !show_hidden;
    -		if (fg != lfg || bg != lbg) {
    -			if (lfg != -1 || lbg != -1)
    -				fprintf(file,"");
    -			fprintf(file,"",fg*8+bg);
    -			lfg = fg;
    -			lbg = bg;
    -		}
    -		fputc(hidden ? ' ' : vtx2iso_table[page->chr[pos]], file);
    -		if (pos % 40 == 39) {
    -			lfg = lbg = -1;
    -			fprintf(file,"\n");
    -		}
    -	}
    -	fprintf(file,"
    \n"); -} - -void -usage(char *prog) -{ - fprintf(stderr,"usage: %s [ options ] vtx-file\n",prog); - fprintf(stderr, - "options: \n" - " -a dump plain ascii (default)\n" - " -c dump colored ascii (using ansi control sequences).\n" - " -h dump html\n"); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - FILE *fp; - char *prog; - int c,output=OUT_ASCII; - - if (NULL != (prog = strrchr(argv[0],'/'))) - prog++; - else - prog = argv[0]; - - for (;;) { - if (-1 == (c = getopt(argc, argv, "ach"))) - break; - switch (c) { - case 'a': - output=OUT_ASCII; - break; - case 'c': - output=OUT_ANSI; - break; - case 'h': - output=OUT_HTML; - break; - default: - usage(prog); - } - } - if (optind+1 != argc) - usage(prog); - - if (NULL == (fp = fopen(argv[optind],"r"))) { - fprintf(stderr,"%s: %s: %s\n",prog,argv[optind],strerror(errno)); - exit(1); - } - - load_vtx(fp, buffer, &page.info, &virtual); - decode_page(buffer, &page, 0, 23); - switch(output) { - case OUT_ASCII: - export_ascii(stdout, &page, 0); - break; - case OUT_ANSI: - export_ansi_ascii(stdout, &page, 0); - break; - case OUT_HTML: - export_html(stdout, &page, 0); - break; - } - return 0; -} diff --git a/src/vtx2ascii-src/misc.h b/src/vtx2ascii-src/misc.h deleted file mode 100644 index 8039941..0000000 --- a/src/vtx2ascii-src/misc.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef MISC_H_INCLUDED -#define MISC_H_INCLUDED - -/* $Id: misc.h,v 1.1 1996/10/14 21:37:00 mb Exp mb $ - * - * Copyright (c) 1994-96 Martin Buck - * Read COPYING for more information - */ - -#include - - -#define VTXVERSION "0.6.970815" -#define VTXNAME "videotext" -#define VTXCLASS "Videotext" -#define VTXWINNAME "VideoteXt" - -#define REQ_MAJOR 1 -#define REQ_MINOR 6 - - -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif -#define SIGN(a) ((a) < 0 ? -1 : ((a) > 0 ? 1 : 0)) -#define STRINGIFY_NOMACRO(str) #str -#define STRINGIFY(str) STRINGIFY_NOMACRO(str) -#define NELEM(a) (sizeof(a) / sizeof(*(a))) - -#ifndef FALSE -#define FALSE 0 -#define TRUE 1 -#endif - -/* It's unbelievable that some systems are unable to provide the most basic ANSI-C features */ -#ifndef INT_MAX -#define INT_MAX 2147483647 -#endif - -#endif /* MISC_H_INCLUDED */ diff --git a/src/vtx2ascii-src/sys/vtx.h b/src/vtx2ascii-src/sys/vtx.h deleted file mode 100644 index c1b4fec..0000000 --- a/src/vtx2ascii-src/sys/vtx.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef VTX_H_INCLUDED -#define VTX_H_INCLUDED - -/* $Id: vtx.h,v 1.6 1997/08/09 00:40:49 mb Exp mb $ - * - * Copyright (c) 1994-97 Martin Buck - * Read COPYING for more information - * - */ - - -typedef unsigned char byte_t; - - -/* videotext ioctls - */ -#define VTXIOCGETINFO 0x7101 /* get version of driver & capabilities of vtx-chipset */ -#define VTXIOCCLRPAGE 0x7102 /* clear page-buffer */ -#define VTXIOCCLRFOUND 0x7103 /* clear bits indicating that page was found */ -#define VTXIOCPAGEREQ 0x7104 /* search for page */ -#define VTXIOCGETSTAT 0x7105 /* get status of page-buffer */ -#define VTXIOCGETPAGE 0x7106 /* get contents of page-buffer */ -#define VTXIOCSTOPDAU 0x7107 /* stop data acquisition unit */ -#define VTXIOCPUTPAGE 0x7108 /* display page on TV-screen */ -#define VTXIOCSETDISP 0x7109 /* set TV-mode */ -#define VTXIOCPUTSTAT 0x710a /* set status of TV-output-buffer */ -#define VTXIOCCLRCACHE 0x710b /* clear cache on VTX-interface (if avail.) */ -#define VTXIOCSETVIRT 0x710c /* turn on virtual mode (this disables TV-display) */ -#define VTXIOCGETQUAL 0x710d /* get current video/videotext quality */ - - -/* definitions for VTXIOCGETINFO - */ -#define SAA5243 0 -#define SAA5246 1 -#define SAA5249 2 -#define SAA5248 3 -#define XSTV5346 4 - -typedef struct { - int version_major, version_minor; /* version of driver; if version_major changes, driver */ - /* is not backward compatible!!! CHECK THIS!!! */ - int numpages; /* number of page-buffers of vtx-chipset */ - int cct_type; /* type of vtx-chipset (SAA5243, SAA5246, SAA5248 or - * SAA5249) */ -} vtx_info_t; - - -/* definitions for VTXIOC{CLRPAGE,CLRFOUND,PAGEREQ,GETSTAT,GETPAGE,STOPDAU,PUTPAGE,SETDISP} - */ -#define MIN_UNIT (1<<0) -#define MIN_TEN (1<<1) -#define HR_UNIT (1<<2) -#define HR_TEN (1<<3) -#define PG_UNIT (1<<4) -#define PG_TEN (1<<5) -#define PG_HUND (1<<6) -#define PGMASK_MAX (1<<7) -#define PGMASK_PAGE (PG_HUND | PG_TEN | PG_UNIT) -#define PGMASK_HOUR (HR_TEN | HR_UNIT) -#define PGMASK_MINUTE (MIN_TEN | MIN_UNIT) - -typedef struct { - int page; /* number of requested page (hexadecimal) */ - int hour; /* requested hour (hexadecimal) */ - int minute; /* requested minute (hexadecimal) */ - int pagemask; /* mask defining which values of the above are set */ - int pgbuf; /* buffer where page will be stored */ - int start; /* start of requested part of page */ - int end; /* end of requested part of page */ - void* buffer; /* pointer to beginning of destination buffer */ -} vtx_pagereq_t; - - -/* definitions for VTXIOC{GETSTAT,PUTSTAT} - */ -#define VTX_PAGESIZE (40 * 24) -#define VTX_VIRTUALSIZE (40 * 49) - -typedef struct { - int pagenum; /* number of page (hexadecimal) */ - int hour; /* hour (hexadecimal) */ - int minute; /* minute (hexadecimal) */ - int charset; /* national charset */ - unsigned delete : 1; /* delete page (C4) */ - unsigned headline : 1; /* insert headline (C5) */ - unsigned subtitle : 1; /* insert subtitle (C6) */ - unsigned supp_header : 1; /* suppress header (C7) */ - unsigned update : 1; /* update page (C8) */ - unsigned inter_seq : 1; /* interrupted sequence (C9) */ - unsigned dis_disp : 1; /* disable/suppress display (C10) */ - unsigned serial : 1; /* serial mode (C11) */ - unsigned notfound : 1; /* /FOUND */ - unsigned pblf : 1; /* PBLF */ - unsigned hamming : 1; /* hamming-error occured */ -} vtx_pageinfo_t; - - -/* definitions for VTXIOCSETDISP - */ -typedef enum { DISPOFF, DISPNORM, DISPTRANS, DISPINS, INTERLACE_OFFSET } vtxdisp_t; - - -/* definitions for VTXIOCGETQUAL - */ -typedef struct { - int video; - int videotext; -} vtx_quality_t; - - -/* tuner ioctls - */ -#define TUNIOCGETINFO 0x7201 /* get version of driver & capabilities of tuner */ -#define TUNIOCRESET 0x7202 /* reset tuner */ -#define TUNIOCSETFREQ 0x7203 /* set tuning frequency (unit: kHz) */ -#define TUNIOCGETFREQ 0x7204 /* get tuning frequency (unit: kHz) */ -#define TUNIOCSETPROG 0x7205 /* set tuning program */ -#define TUNIOCGETPROG 0x7206 /* get tuning program */ - - -typedef struct { - int version_major, version_minor; /* version of driver; if version_major changes, driver */ - /* is not backward compatible!!! CHECK THIS!!! */ - unsigned freq : 1; /* tuner can be set to arbitrary frequency */ - unsigned prog : 1; /* tuner stores several programs */ - unsigned scan : 1; /* tuner supports scanning */ - unsigned autoscan : 1; /* tuner supports scanning with automatic stop */ - unsigned afc : 1; /* tuner supports AFC */ - unsigned dummy1, dummy2, dummy3, dummy4, dummy5, dummy6, dummy7, dummy8, dummy9, dummy10, - dummy11 : 1; - int dummy12, dummy13, dummy14, dummy15, dummy16, dummy17, dummy18, dummy19; -} tuner_info_t; - - -/* i2c ioctls - */ - -#define I2CIOCWRITE 0x7300 /* write raw data to I²C-bus (needs RAW_I2C_SUPPORT) */ -#define I2CIOCREAD 0x7301 /* read raw data from I²C-bus (needs RAW_I2C_SUPPORT) */ - - -/* definitions for I2CIOC{WRITE,READ} - */ -typedef struct { - int adr; - int count; - byte_t *buffer; -} i2c_raw_t; - -#endif /* VTX_H_INCLUDED */ diff --git a/src/vtx2ascii-src/vtx.cgi b/src/vtx2ascii-src/vtx.cgi deleted file mode 100755 index d921f05..0000000 --- a/src/vtx2ascii-src/vtx.cgi +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/perl -use CGI; - -# config -$SPOOL="/home/kraxel/vtx"; -$VTX2ASCII="/home/kraxel/bin/vtx2ascii"; - -####################################################################### -# create time string - -@WEEK = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); -@MON = ('Jan','Feb','Mar','Apr','May','Jun', - 'Jul','Aug','Sep','Oct','Nov','Dec'); - -sub time2str { - @tm = gmtime($_[0]); - sprintf ("%s, %02d %s %04d %02d:%02d:%02d GMT", - $WEEK[$tm[6]],$tm[3],$MON[$tm[4]],$tm[5]+1900,$tm[2],$tm[1],$tm[0]); -} - -####################################################################### -# helper functions - -sub start_page { - local($title,$file) = @_; - - if ($file ne "") { - @inode = stat $file; - printf("Last-modified: %s\n",time2str(@inode[9])); - } - print < - -videotext: $title - - -EOF -} - -sub finish_page { - print "\n"; -} - -sub panic { - local($text) = @_; - - start_page("PANIC"); - print "

    PANIC

    $text"; - &finish_page; - exit; -} - -sub addlink() { - local($nr) = @_; - - $links{$nr} = 1; - return $nr; -} - -####################################################################### -# main - -$cgi = new CGI; - -if ($cgi->path_info eq "" || $cgi->path_info =~ /^\/[^\/]+$/) { - print $cgi->redirect($cgi->url . $cgi->path_info . "/"); - exit; -} -($dummy,$station,$page) = split(/\//,$cgi->path_info); - -# entry page - station list -if ($station !~ /\S/) { - opendir DIR, $SPOOL || panic("can't open dir $SPOOL: $@"); - &start_page("station list",$SPOOL); - print "

    station list

    \n
      \n"; - while ($file = readdir(DIR)) { - next if ($file =~ /^\./); - next unless -d "$SPOOL/$file"; - print "
    • $file\n"; - } - print "
    \n"; - &finish_page; - exit; -} - -# station dir - spage list -if ($page !~ /\S/) { - opendir DIR, "$SPOOL/$station" || - panic("can't open dir $SPOOL/$station: $@"); - &start_page("$station - page list","$SPOOL/$station"); - print "

    $station - page list

    \n\n"; - print "[station list]
      \n"; - while ($file = readdir(DIR)) { - next unless ($file =~ /\.vtx/); - print "
    • $file\n"; - } - print "
    \n"; - &finish_page; - exit; -} - -# print page -unless (-f "$SPOOL/$station/$page") { - # sub-page check - if ($page =~ s/_00.vtx/_01.vtx/ && -f "$SPOOL/$station/$page") { - print $cgi->redirect($cgi->url . "/$station/$page"); - exit; - } - panic("$SPOOL/$station/$page: not found"); -} - -# read -undef $/; -open VTX,"$VTX2ASCII -h $SPOOL/$station/$page |" || - panic("can't run $VTX2ASCII: $@"); -$data = ; -close VTX; - -# look for links -$data =~ s/(\d\d\d)/&addlink($1)/eg; - -# print -start_page("$station - $page","$SPOOL/$station/$page"); -print "

    $station - $page

    \n"; -print "[station list]   "; -print "[page list]   "; -if ($page =~ /(\d\d\d)_(\d\d).vtx/ && $2 > 0) { - printf "[prev subpage]   ",$1,$2-1; - printf "[next subpage]   ",$1,$2+1; -} -print "
    \n"; -foreach $item (sort keys %links) { - print "$item\n"; -} -print "
    \n"; -print "$data"; -&finish_page; -exit; diff --git a/src/vtx2ascii-src/vtx_assert.h b/src/vtx2ascii-src/vtx_assert.h deleted file mode 100644 index e4dce2a..0000000 --- a/src/vtx2ascii-src/vtx_assert.h +++ /dev/null @@ -1,46 +0,0 @@ -/* $Id: vtx_assert.h,v 1.1 1996/10/01 21:25:20 mb Exp mb $ - * - * Copyright (c) 1994-96 Martin Buck - * Read COPYING for more information - */ - -/* This header file provides an alternative to the standard assert: You can - * choose wheter or not your program should dump core when an assertion - * fails. If you don't define ASSERT_DUMP_CORE, your program will print the - * `failed assertion'-message and call exit(1) without a coredump. - * - * The reason for this is that you can lock up your X-server when assert - * calls abort() at the wrong time (probably during grabs). If you can't - * login on a serial line or over the network to kill the X-server, you will - * have to reboot your machine (I once experienced this with another - * application -- not even XFree's ZapServer-key did work)! - * - * There has been a report that in VideoteXt an assertion fails when a - * station broadcasts a multipage-extension-table. I wasn't able to - * reproduce this and I don't think that this was the reason for the abort, - * but I decided to use this alternative assert just to make sure VideoteXt - * doesn't do bad things[tm] to your machine :-) - * - * But if you get `failed assertion'-messages, *please* report them to me! - */ - -#include - -#undef assert -#undef __assert - -#ifdef NDEBUG -#define assert(ignore) ((void) 0) -#else - -#define assert(exp) ((void) ((exp) ? 0 : __assert (#exp, __FILE__, __LINE__))) - -#ifdef ASSERT_DUMP_CORE -#define __assert(exp, file, lineno) \ - (fprintf (stderr, "%s:%u: failed assertion `%s'\n", file, lineno, exp), abort (), 0) -#else -#define __assert(exp, file, lineno) \ - (fprintf (stderr, "%s:%u: failed assertion `%s'\nTerminating\n", file, lineno, exp), \ - exit (1), 0) -#endif -#endif diff --git a/src/vtx2ascii-src/vtxdecode.c b/src/vtx2ascii-src/vtxdecode.c deleted file mode 100644 index 4ad0d1f..0000000 --- a/src/vtx2ascii-src/vtxdecode.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * vtxdecode.c: Routines to decode VTX-pages & convert from magic-cookie-VTX-attributes to - * 'normal' attributes usable by x_vtx_redraw() - * - * $Id: vtxdecode.c,v 1.2 1997/03/26 00:16:54 mb Exp mb $ - * - * Copyright (c) 1994-96 Martin Buck - * Read COPYING for more information - * - */ - -#include -#include "vtx_assert.h" -#include "cct.h" -#include "vtxtools.h" -#include "misc.h" -#include "vtxdecode.h" - - -/* Translation tables to convert VTX font-layout (with different national charsets) to - * X-Window font layout - */ -const chr_t cct2vtx_table[8][96] = { - /* English */ - { 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, - 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f }, - /* French */ - { 0x20,0x21,0x22,0Xc0,0Xc1,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0Xc2,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0Xc3,0Xc4,0Xc5,0Xc6,0x5f, - 0Xc7,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0Xc8,0Xc9,0Xca,0Xcb,0x7f }, - /* Swedish */ - { 0x20,0x21,0x22,0X5f,0Xcc,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0Xcd,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0Xce,0Xcf,0Xd0,0Xd1,0Xd2, - 0Xc0,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0Xd3,0Xd4,0Xd5,0Xd6,0x7f }, - /* Unknown */ - { 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, - 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f }, - /* German */ - { 0x20,0x21,0x22,0X5f,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0Xd7,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0Xce,0Xcf,0Xd1,0Xd8,0Xd2, - 0Xd9,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0Xd3,0Xd4,0Xd6,0Xda,0x7f }, - /* Spanish */ - { 0x20,0x21,0x22,0Xcb,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0Xcb,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0Xde,0Xc0,0Xdf,0Xe2,0Xe3, - 0Xdc,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0Xd6,0Xdd,0Xc7,0Xc2,0x7f }, - /* Italian */ - { 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0Xc0,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0Xd9,0Xcb,0x5d,0x5e,0x5f, - 0Xc5,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0Xc2,0Xe0,0Xc7,0Xe1,0x7f }, - /* Unknown */ - { 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, - 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f } -}; - - -/* Translation table to convert VideoteXt-X-Window font-layout to ISO 8859-1. - * You should have a complete ISO-Font when editing the following table! - */ -const char vtx2iso_table[256] = - " " - " !\"#$%&'()*+,-./0123456789:;<=>?" //" !\"£$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" //"@ABCDEFGHIJKLMNOPQRSTUVWXYZ<½>^#" - "`abcdefghijklmnopqrstuvwxyz{|}~ " //"-abcdefghijklmnopqrstuvwxyz¼|¾÷#" - " " - " " //TODO: completely wrong - "éïàëêùîèâôûç¤ÉÄÖÅÜ_äöåü§^°ß¡¿ñáí" //TODO: completely wrong - "òìóú ? ";//TODO: completely wrong -/* The same table with all characters mapped to lowercase */ -const char vtx2iso_lc_table[256] = - " " - " !\"#$%&'()*+,-./0123456789:;<=>?" //" !\"£$%&'()*+,-./0123456789:;<=>?" - "@abcdefghijklmnopqrstuvwxyz[\\]^_" //"@abcdefghijklmnopqrstuvwxyz<½>^#" - "`abcdefghijklmnopqrstuvwxyz{|}~ " //"-abcdefghijklmnopqrstuvwxyz¼|¾÷#" - " " - " " //TODO: completely wrong - "éïàëêùîèâôûç¤Éäöåü_äöåü§^°ß¡¿ñáí" //TODO: completely wrong - "òìóú ? ";//TODO: completely wrong -/* All word delimiters in videotext's subset of ISO 8859-1 */ -//const char vtxiso_worddelim[] = " !\"£$%&'()*+,-./:;<=>?@<½>^#-¼|¾÷¤_§^°¡¿"; -const char vtxiso_worddelim[] = " !\"#$%&'()*+,-./:;<=>?@<\\>^_`{|}~¤_§^°¡¿"; - - -/* Decode lines y1 - y2 of original VTX-page in pgbuf to vtxpage usable by VideoteXt using - * national charset lang - * Return VTXOK if OK, VTXEINVAL if start-/end-line invalid - */ -int -decode_page(const byte_t *pgbuf, vtxpage_t *page, int y1, int y2) { - int line, col, pos, graphics, grhold, doubleht, nextattr = 0; - static int lang; - attrib_t *lastattr, default_attrib = 7, next_attrib; - chr_t chr, *lastchr, default_chr = ' '; - - if (y1 > y2 || y1 < 0 || y2 > 23) - return VTXEINVAL; - - if (!page->info.hamming) - lang = page->info.charset; - - pos = y1 * 40; - doubleht = 0; - for (line = y1; line <= y2; line++) { - lastchr = &default_chr; - lastattr = &default_attrib; - graphics = grhold = 0; - if (doubleht) { - for (col = 0; col <= 39; col++) { - if (page->attrib[pos - 40] & VTX_DOUBLE1) { - page->chr[pos] = page->chr[pos - 40]; - page->chr[pos - 40] = ' '; - page->attrib[pos] = (page->attrib[pos - 40] & ~VTX_DOUBLE1) | VTX_DOUBLE2; - } else { - page->chr[pos] = ' '; - page->attrib[pos] = page->attrib[pos - 40]; - } - pos++; - } - doubleht = 0; - } else { - for (col = 0; col <= 39; col++) { - chr = pgbuf[pos]; - if (!vtx_chkparity(&chr)) { - page->chr[pos] = 254; /* Parity error */ - page->attrib[pos] = 7; - } else if (chr >= 32 && chr <= 127) { /* Normal character */ - page->attrib[pos] = *lastattr; - if (!graphics || (chr >= 64 && chr <= 95)) { - page->chr[pos] = cct2vtx_table[lang][chr - 32]; - } else { - page->chr[pos] = chr + (chr >= 96 ? 64 : 96); - } - } else { - page->chr[pos] = ((grhold && graphics ) ? *lastchr : ' '); - if (chr <= 7) { /* Set alphanumerics-color */ - page->attrib[pos] = *lastattr; - next_attrib = (*lastattr & ~(VTX_COLMASK | VTX_HIDDEN)) + chr; - nextattr = 1; - graphics = 0; - } else if (chr == 8 || chr == 9) { /* Flash on/off */ - page->attrib[pos] = (*lastattr & ~VTX_FLASH) + VTX_FLASH * (chr == 8); - } else if (chr == 10 || chr == 11) { /* End/start box */ - page->attrib[pos] = (*lastattr & ~VTX_BOX) + VTX_BOX * (chr == 11); - } else if (chr == 12 || chr == 13) { /* Normal/double height */ - page->attrib[pos] = (*lastattr & ~VTX_DOUBLE1) + VTX_DOUBLE1 * (chr == 13); - if (chr == 13) - doubleht = 1; - } else if (chr == 14 || chr == 15 || chr == 27) { /* SO, SI, ESC (ignored) */ - page->attrib[pos] = *lastattr; - } else if (chr >= 16 && chr <= 23) { /* Set graphics-color */ - page->attrib[pos] = *lastattr; - next_attrib = (*lastattr & ~(VTX_COLMASK | VTX_HIDDEN)) + chr - 16; - nextattr = 1; - graphics = 1; - } else if (chr == 24) { /* Conceal display */ - page->attrib[pos] = *lastattr | VTX_HIDDEN; - } else if (chr == 25 || chr == 26) { /* Contiguous/separated graphics */ - page->attrib[pos] = (*lastattr & ~VTX_GRSEP) + VTX_GRSEP * (chr == 26); - } else if (chr == 28) { /* Black background */ - page->attrib[pos] = *lastattr & ~VTX_BGMASK; - } else if (chr == 29) { /* Set background */ - page->attrib[pos] = (*lastattr & ~VTX_BGMASK) + ((*lastattr & VTX_COLMASK) << 3); - } else if (chr == 30 || chr == 31) { /* Hold/release graphics */ - page->attrib[pos] = *lastattr; - grhold = (chr == 30); - if (grhold && graphics) - page->chr[pos] = *lastchr; - } else { - assert(0); - } - } - lastchr = page->chr + pos; - if (nextattr) { - lastattr = &next_attrib; - nextattr = 0; - } else { - lastattr = page->attrib + pos; - } - pos++; - } - } - } - return VTXOK; -} diff --git a/src/vtx2ascii-src/vtxdecode.h b/src/vtx2ascii-src/vtxdecode.h deleted file mode 100644 index b56bf75..0000000 --- a/src/vtx2ascii-src/vtxdecode.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef VTXDECODE_H_INCLUDED -#define VTXDECODE_H_INCLUDED - -/* $Id: vtxdecode.h,v 1.3 1997/03/26 00:17:34 mb Exp mb $ - * - * Copyright (c) 1994-96 Martin Buck - * Read COPYING for more information - */ - - -#include - - -#define VTXOK 0 -#define VTXEINVAL -1 -#define VTXEPARITY -2 - -#define VTX_COLMASK 0x07 /* I rely on the position of the VTX_COLMASK & VTX_BGMASK bits! */ -#define VTX_BGMASK (0x07 << 3) -#define VTX_GRSEP (1 << 7) -#define VTX_HIDDEN (1 << 8) -#define VTX_BOX (1 << 9) -#define VTX_FLASH (1 << 10) -#define VTX_DOUBLE1 (1 << 11) -#define VTX_DOUBLE2 (1 << 12) -#define VTX_INVERT (1 << 13) -#define VTX_DOUBLE (VTX_DOUBLE1 | VTX_DOUBLE2) - - -typedef unsigned char chr_t; -typedef unsigned short attrib_t; -typedef struct { - chr_t chr[VTX_PAGESIZE]; - attrib_t attrib[VTX_PAGESIZE]; - vtx_pageinfo_t info; -} vtxpage_t; - - -extern const chr_t cct2vtx_table[][96]; -extern const char vtx2iso_table[], vtx2iso_lc_table[], vtxiso_worddelim[]; - - -int decode_page(const byte_t *pgbuf, vtxpage_t *page, int y1, int y2); - -#endif /* VTXDECODE_H_INCLUDED */ diff --git a/src/vtx2ascii-src/vtxtools.c b/src/vtx2ascii-src/vtxtools.c deleted file mode 100644 index 40c9297..0000000 --- a/src/vtx2ascii-src/vtxtools.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * vtxtools.c: Misceallaneous routines for VideoteXt (parity checking, handling of hexadecimal - * page-numbers) - * - * $Id: vtxtools.c,v 1.1 1996/10/14 21:36:23 mb Exp mb $ - * - * Copyright (c) 1994-96 Martin Buck - * Read COPYING for more information - * - */ - -#include -#include "misc.h" -#include "vtxtools.h" - - -static byte_t parity_table[256]; -static int init_done; - - - -static void -tools_init(void) { - int pos, val, bit; - - for (pos = 0; pos <= 255; pos++) { /* Set up parity_table: If (parity_table[foo] & 0x80), */ - bit = 0; /* foo has odd number of bits set */ - val = pos; - while (val) { /* Count number of set bits in val; see K&R, Exercise 2-9 */ - bit ^= 0x80; - val &= val - 1; - } - parity_table[pos] = bit | 0x7f; - } - /* parity_table is also used for hamming decoding: If (parity_table[foo] & 0x40), foo has - * more than one bit-error and can't be corrected; otherwise the correct(ed) value is - * parity_table[foo] & 0xf - */ - for (pos = 0; pos <= 15; pos++) { - val = ( !(pos & 1) ^ !!(pos & 4) ^ !!(pos & 8)) << 0 | !!(pos & 1) << 1 | - ( !(pos & 1) ^ !!(pos & 2) ^ !!(pos & 8)) << 2 | !!(pos & 2) << 3 | - ( !(pos & 1) ^ !!(pos & 2) ^ !!(pos & 4)) << 4 | !!(pos & 4) << 5 | - (!!(pos & 2) ^ !!(pos & 4) ^ !!(pos & 8)) << 6 | !!(pos & 8) << 7; - for (bit = 0; bit <= 8; bit++) { - parity_table[val ^ ((1 << bit) & 0xff)] &= (0x80 | pos); - } - } - init_done = TRUE; -} - - -/* Check parity of *val (parity bit is bit 7, odd parity) - * Clear bit 7 of *val if parity OK & return TRUE, FALSE otherwise - */ -int -vtx_chkparity(byte_t *val) { - if (!init_done) - tools_init(); - if (parity_table[*val] & 0x80) { - *val &= 0x7f; - return TRUE; - } else return FALSE; -} - - -/* Add odd parity bit to val - */ -byte_t -vtx_mkparity(byte_t val) { - if (!init_done) - tools_init(); - val &= 0x7f; - return val | ((parity_table[val] & 0x80) ? 0 : 128); -} - - -/* Check hamming-encoding of val, return decoded value if OK, -1 otherwise - */ -int -vtx_chkhamming(byte_t val) { - if (!init_done) - tools_init(); - if (parity_table[val] & 0x40) { - return -1; - } else { - return parity_table[val] & 0xf; - } -} - - -/* Increase page-number. Skip over hexadecimal pages - */ -int -inc_vtxpage(int page) { - page++; - if ((page & 0xf) >= 0xa) - page = (page & ~0xf) + 0x10; - if ((page & 0xf0) >= 0xa0) - page = (page & ~0xff) + 0x100; - if (page >= 0x899) - page = 0x100; - return page; -} - - -/* Decrease page-number. Skip over hexadecimal pages - */ -int -dec_vtxpage(int page) { - page--; - if ((page & 0xf) >= 0xa) - page = (page & ~0xf) + 9; - if ((page & 0xf0) >= 0xa0) - page = (page & ~0xff) + 0x99; - if (page < 0x100) - page = 0x899; - return page; -} - - -int -vtx_hex2dec(int pgnum) { - return (pgnum / 0x100) * 100 + ((pgnum / 0x10) % 0x10) * 10 + (pgnum % 0x10); -} - - -int -vtx_dec2hex(int pgnum) { - return (pgnum / 100) * 0x100 + ((pgnum / 10) % 10) * 0x10 + (pgnum % 10); -} - - -int -vtx_chkpgnum(int pgnum, int hex_ok) { - if (hex_ok) { - return (pgnum >= 0x100 && pgnum <= 0x8ff); - } else { - return (pgnum >= 0x100 && pgnum <= 0x899 && (pgnum & 0xff) <= 0x99 && (pgnum & 0xf) <= 9); - } -} diff --git a/src/vtx2ascii-src/vtxtools.h b/src/vtx2ascii-src/vtxtools.h deleted file mode 100644 index b819d84..0000000 --- a/src/vtx2ascii-src/vtxtools.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef VTXTOOLS_H_INCLUDED -#define VTXTOOLS_H_INCLUDED - -/* $Id: vtxtools.h,v 1.1 1996/10/14 21:36:25 mb Exp mb $ - * - * Copyright (c) 1994-96 Martin Buck - * Read COPYING for more information - */ - - -#include - - -int vtx_chkparity(byte_t *val); -byte_t vtx_mkparity(byte_t val); -int vtx_chkhamming(byte_t val); -int inc_vtxpage(int page); -int dec_vtxpage(int page); -int vtx_hex2dec(int pgnum); -int vtx_dec2hex(int pgnum); -int vtx_chkpgnum(int pgnum, int hex_ok); - -#endif /* VTXTOOLS_H_INCLUDED */ -- 2.39.3