⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvbtext.c

📁 MiniWinOuterSM MiniWinOuterSM
💻 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 + -