📄 dvbtext.c
字号:
/*
一个PES流中可能存在8个不同的图文广播杂志,
每个图文广播杂志可以有多个页面的数据
*/
#include <stdio.h>
//#include <conio.h>
#include <stdlib.h>
#include "dvbtext.h"
//#include <fcntl.h>
//#include <sys/types.h>
//#include <sys/stat.h>
//#include <io.h>
typedef struct mag_struct{
int valid;
int mag;
unsigned char flags;
unsigned char lang;
int pnum,sub;
unsigned char pagebuf[25*40];
}DVBTextPage;
void load(DVBTextPage pg);
// FROM vbidecode
// unham 2 bytes into 1, report 2 bit errors but ignore them
unsigned char unham(unsigned char a,unsigned char b)
{
unsigned char c1,c2;
c1=unhamtab[a];
c2=unhamtab[b];
//if ((c1|c2)&0x40)PrDbgPrintf("bad ham!");
return (c2<<4)|(0x0f&c1);
}
void set_line(DVBTextPage *mag, int line, unsigned char* data,int pnr) {
unsigned char c;
FILE * fd;
char fname[80];
unsigned char buf;
if (line==0) {
mag->valid=1;
memset(mag->pagebuf,' ', 25*40);
mag->pnum=unham(data[0],data[1]); // The lower two (hex) numbers of page
if (mag->pnum==0xff) return; // These are filler lines. Can use to update clock
PrDbgPrintf("pagenum: %03x\n",c+mag->mag*0x100);
mag->flags=unham(data[2],data[3])&0x80;
mag->flags|=(c&0x40)|((c>>2)&0x20);
c=unham(data[6],data[7]);
mag->flags|=((c<<4)&0x10)|((c<<2)&0x08)|(c&0x04)|((c>>1)&0x02)|((c>>4)&0x01);
mag->lang=((c>>5) & 0x07);
mag->sub=(unham(data[4],data[5])<<8)|(unham(data[2],data[3])&0x3f7f);
// mag->pnum = (mag->mag<<8)|((mag->sub&0x3f7f)<<16)|page;
PrDbgPrintf("pnum: %x, sub: %x\n",/*page,*/mag->pnum,mag->sub);
}
if (mag->valid) {
if (line <= 23)
memcpy(mag->pagebuf+40*line,data,40);
if (line==23) {
/*sprintf(fname,"%03x_%02x.vtx",mag->pnum+(mag->mag*0x100),mag->sub&0xff);
//sprintf(fname,"%s/%03x_%02x.vtx",VTXDIR,pnr,mag->pnum+(mag->mag*0x100),mag->sub&0xff);
/*fprintf(stderr,"Writing to file %s\n",fname);
if ((fd=fopen(fname,"w"))) {
fwrite("VTXV4",1,5,fd);
buf=0x01; fwrite(&buf,1,1,fd);
buf=mag->mag; fwrite(&buf,1,1,fd);
buf=mag->pnum; fwrite(&buf,1,1,fd);
buf=0x00; fwrite(&buf,1,1,fd); //subpage
buf=0x00; fwrite(&buf,1,1,fd);
buf=0x00; fwrite(&buf,1,1,fd);
buf=0x00; fwrite(&buf,1,1,fd);
fwrite(mag->pagebuf,1,24*40,fd);
fclose(fd);
}*/
load(*mag);
mag->valid=0;
}
}
}
#define BOOL unsigned char
#define false 0
#define true 1
static int hextodec(int i) {
return ((((i >> 8) & 0x0f) * 100) +
(((i >> 4) & 0x0f) * 10) +
(i & 0x0f));
}
unsigned char letter[1000],attrib[1000],color[1000],link_to[1000];
void detectLinks() {
int i;
int status=0;
BOOL success = false;
int link;
char buffer[3];
const char *vtx_separators = " .-/";
memset(buffer,0,3);
for (i=0; i < 960; i++) {
link_to[i]=0;
if ((i % 40) == 0) {
if (status==4) {
success = true;
}
status=1;
}
if (strchr(vtx_separators,letter[i])) {
if (status==4) {
success = true;
}
status=1;
}
else if ((letter[i]>='0') && (letter[i]<='9')) {
if ((status==1) && (letter[i]!='0')) {
buffer[0]=letter[i];
status++;
}
else if ((status==2) || (status==3)){
buffer[status-1]=(char)letter[i];
status++;
}
else {
status=0;
}
}
else {
status=0;
}
if (success) {
link=(buffer[0]-'0')*100
+(buffer[1]-'0')*10
+(buffer[2]-'0');
link_to[i-3]=link;
link_to[i-2]=link;
link_to[i-1]=link;
//printf("link[%d]=%d\r\n",i,link);
success=false;
}
}
if (status==4) {
link=(buffer[0]-'0')*100
+(buffer[1]-'0')*10
+(buffer[2]-'0');
link_to[957]=link;
link_to[958]=link;
link_to[959]=link;
//printf("link[%d]=%d\r\n",i,link);
}
}
void load(DVBTextPage pg)
{//解码并显示杂志页面
//InputStream i_stream;
int c=0, i, j;
unsigned char last_letter = ' ';
unsigned char last_color = 7;
unsigned char new_color = 7;
BOOL parity = false;
BOOL graphics = false;
BOOL grhold = false;
BOOL copy_line = false;
BOOL double_height = false;
BOOL sep_graphics = false;
BOOL conceal = false;
BOOL flash = false;
//String last_line = new String(" - Hist + - Chan + Reveal Home ");
int pg_no,page_number;
// first stop flash-thread
/*if (flash_thread.isAlive()) {
flash_thread.suspend();
}*/
// read vtx header information
//i_stream = page.openStream();
//i_stream.read(header);
//pg_no = i_stream.read() + (i_stream.read() << 8);
page_number=hextodec(pg.pnum);
//hour = i_stream.read();
//minute = i_stream.read();
//charset =i_stream.read();
if ((pg.lang>7) || (pg.lang<0)) {//charset
printf("charset %d not supported",pg.lang);
pg.lang=0;
}
//dummy = i_stream.read();
//dummy = i_stream.read();
i = 0;
// read the teletext data
while(i<1000){
c=pg.pagebuf[i];
if ((i % 40) == 0){
// begin new line -> reset attributes
graphics = false;
grhold = false;
sep_graphics = false;
conceal = false;
flash = false;
double_height = false;
last_letter =' ';
last_color =7;
new_color =7;
}
if (((i % 40) == 0) && (copy_line)) {
// double height -> forget next line
i+=39;//i_stream.skip((long)39);
for (j=0; j<40; j++) {
color[i]=color[i-40];
if ((attrib[i-40] & 0x03) > 0) {
letter[i]=letter[i-40];
attrib[i]=((attrib[i-40] & 0xfc) | 0x02);
}
else {
letter[i]=' ';
}
i++;
}
copy_line=false;
}else {
parity=right_parity[c];// check parity
c = (c & 0x7F);// strip parity bit
// set actual attributes
color[i]=last_color;
attrib[i]=0;
if (double_height) attrib[i] =(attrib[i] | 0x01);
if (sep_graphics) attrib[i] =(attrib[i] | 0x04);
if (conceal) attrib[i] =(attrib[i] | 0x08);
if (flash) attrib[i] =(attrib[i] | 0x10);
// decode read byte
if (!parity)
letter[i] =254;
else if ((c >= 32) && (c <= 127)) {
if (!graphics || ((c >= 64) && (c <= 95))) {
letter[i] =c;//cct2vtx_table[pg.lang][c - 32];
} else
letter[i] = (c + ((c >= 96) ? 64 : 96));
}else {
letter[i] = ((grhold && graphics )?last_letter :' ');
if (c <= 7) {// Set alphanumerics-color
graphics = false;
new_color = ((last_color & 0xF0) | c) ;
conceal = false;
}else if (c == 8)// Flashing text on
flash = true;
else if (c == 9)// Flashing text off
flash = false;
else if (c == 12) // Set normal height
double_height = false;
else if (c == 13) {// Set double height
double_height = true;
copy_line = true;
}else if ((c >= 16) && (c <= 23)) {
// Set graphics-color
graphics = true;
new_color =(last_color & 0xF0)|(c - 16) ;
conceal = false;
}else if (c == 24)// Conceal display
conceal = true;
else if (c == 25)// Contiguous graphics
sep_graphics = false;
else if (c == 26) {// Separated graphics
sep_graphics = true;
attrib[i] = attrib[i] | 0x04;
}else if (c == 28) {// Black background
new_color = last_color & 0x0F;
color[i] = new_color;
}else if (c == 29) {// Set background
new_color = ((last_color & 0x0F)|((last_color & 0x0F) << 4));
color[i] = new_color;
}else if (c == 30) {// Hold graphics
grhold = true;
if (graphics)letter[i]=last_letter;
}else if (c == 31)// Release graphics
grhold = false;
}
last_letter = letter[i];
last_color = new_color;
// handle the first 12 letters
if (i<12) {
if ((i>3) && (i<7)) {
letter[i]='-';
color[i]=2;
}else {
if (i==8) letter[i]=(page_number / 100) + '0';
else if (i==9) letter[i]=((page_number / 10) % 10)+ '0';
else if (i==10) letter[i]=(page_number % 10) + '0';
else letter[i]=' ';
color[i]= 7;
}
}
i++;
}
}
detectLinks();
for (i=960; i<1000; i++) {
// letter
//letter[i]=(byte) last_line.charAt(i-960);
// attributes
attrib[i]=0;// color
if (i==960)color[i]=0x00; //black
else if (i<971)color[i]=0x20;// green
else if (i<981)color[i]=0x10;// red
else if (i<991)color[i]=0x30; // yellow
else color[i]=0x60; // cyan
// links
if ((i>=961) && (i<=963))link_to[i]=10;
else if ((i>=968) && (i<=970))link_to[i]=11;
else if ((i>=971) && (i<=973))link_to[i]=12;
else if ((i>=978) && (i<=980))link_to[i]=13;
else if ((i>=983) && (i<=989))link_to[i]=14;
else if ((i>=994) && (i<=997))link_to[i]=100;
}
PrDbgPrintf("\r\n=========>>>===============>>>>\r\n");
for(i=0;i<1000;i++){
if(i%40==0)
PrDbgPrintf("\r\n");
PrDbgPrintf("%c",letter[i]);
}//输出40*25的文本页面
}
DVBTextPage mpage[8];
static int maxpage,minpage;
void TTXPes(void *pesdata,int len)
{
unsigned char*pbuf=(unsigned char*)pesdata;
int i,j,mpag,mag,pack;
pbuf+=46;
for(i=0;i<8;i++)
mpage[i].valid=1;
for (i=0;i<(len-46)/46;i++) {
if (pbuf[0]==2) {
for (j=4;j<46;j++)
pbuf[j]=invtab[pbuf[j]];
mpag=unham(pbuf[4],pbuf[5]);
mag=mpag&7;
pack=(mpag>>3)&0x1f;
//PrDbgPrintf("Set magazine %d Line:%d\r\n",mag,pack);
/*if(pack==27){
int k;
PrDbgPrintf("Line 27:");
for(k=0;k<40;k++)
PrDbgPrintf("%c ",pbuf[6+k]);
PrDbgPrintf("\r\n");
}*/
set_line(&mpage[mag],pack,pbuf+6,0);
}
pbuf+=46;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -