/*
* libzvbi - Teletext decoder
*
* Copyright (C) 2000, 2001 Michael H. Schimek
*
* Based on code from AleVT 1.5.1
* Copyright (C) 1998, 1999 Edgar Toernig <froese@gmx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: vt.h,v 1.8 2005/10/04 10:06:33 mschimek Exp $ */
#ifndef VT_H
#define VT_H
#include <inttypes.h>
#include "bcd.h"
#include "format.h"
#ifndef VBI_DECODER
#define VBI_DECODER
typedef struct vbi_decoder vbi_decoder;
#endif
/**
* @internal
*
* Page function code according to ETS 300 706, Section 9.4.2,
* Table 3: Page function and page coding bits (packets X/28/0 Format 1,
* X/28/3 and X/28/4).
*/
typedef enum {
PAGE_FUNCTION_EPG = -4, /* libzvbi private */
PAGE_FUNCTION_TRIGGER = -3, /* libzvbi private */
PAGE_FUNCTION_DISCARD = -2, /* libzvbi private */
PAGE_FUNCTION_UNKNOWN = -1, /* libzvbi private */
PAGE_FUNCTION_LOP,
PAGE_FUNCTION_DATA_BROADCAST,
PAGE_FUNCTION_GPOP,
PAGE_FUNCTION_POP,
PAGE_FUNCTION_GDRCS,
PAGE_FUNCTION_DRCS,
PAGE_FUNCTION_MOT,
PAGE_FUNCTION_MIP,
PAGE_FUNCTION_BTT,
PAGE_FUNCTION_AIT,
PAGE_FUNCTION_MPT,
PAGE_FUNCTION_MPT_EX
} page_function;
/**
* @internal
* Page coding code according to ETS 300 706, Section 9.4.2,
* Table 3: Page function and page coding bits (packets X/28/0 Format 1,
* X/28/3 and X/28/4).
*/
typedef enum {
PAGE_CODING_UNKNOWN = -1, /* libzvbi private */
PAGE_CODING_PARITY,
PAGE_CODING_BYTES,
PAGE_CODING_TRIPLETS,
PAGE_CODING_HAMMING84,
PAGE_CODING_AIT,
PAGE_CODING_META84
} page_coding;
/**
* @internal
*
* DRCS character coding according to ETS 300 706, Section 14.2,
* Table 31: DRCS modes; Section 9.4.6, Table 9: Coding of Packet
* X/28/3 for DRCS Downloading Pages.
*/
typedef enum {
DRCS_MODE_12_10_1,
DRCS_MODE_12_10_2,
DRCS_MODE_12_10_4,
DRCS_MODE_6_5_4,
DRCS_MODE_SUBSEQUENT_PTU = 14,
DRCS_MODE_NO_DATA
} drcs_mode;
/*
Only a minority of pages need this
*/
typedef struct {
int black_bg_substitution;
int left_side_panel;
int right_side_panel;
int left_panel_columns;
} ext_fallback;
#define VBI_TRANSPARENT_BLACK 8
typedef struct {
unsigned int designations;
int char_set[2]; /* primary, secondary */
int def_screen_color;
int def_row_color;
int foreground_clut; /* 0, 8, 16, 24 */
int background_clut;
ext_fallback fallback;
uint8_t drcs_clut[2 + 2 * 4 + 2 * 16];
/* f/b, dclut4, dclut16 */
vbi_rgba color_map[40];
} vt_extension;
/**
* @internal
*
* Packet X/26 code triplet according to ETS 300 706, Section 12.3.1.
*/
typedef struct vt_triplet {
unsigned address : 8;
unsigned mode : 8;
unsigned data : 8;
} /* __attribute__ ((packed)) */ vt_triplet;
typedef struct vt_pagenum {
unsigned type : 8;
unsigned pgno : 16;
unsigned subno : 16;
} pagenum;
typedef struct {
pagenum page;
uint8_t text[12];
} ait_entry;
typedef vt_triplet enhancement[16 * 13 + 1];
#define NO_PAGE(pgno) (((pgno) & 0xFF) == 0xFF)
/* 0xE03F7F nat. char. subset and sub-page */
#define C4_ERASE_PAGE 0x000080 /* erase previously stored packets */
#define C5_NEWSFLASH 0x004000 /* box and overlay */
#define C6_SUBTITLE 0x008000 /* box and overlay */
#define C7_SUPPRESS_HEADER 0x010000 /* row 0 not to be displayed */
#define C8_UPDATE 0x020000
#define C9_INTERRUPTED 0x040000
#define C10_INHIBIT_DISPLAY 0x080000 /* rows 1-24 not to be displayed */
#define C11_MAGAZINE_SERIAL 0x100000
/**
* @internal
*
* This structure holds a raw Teletext page as decoded by
* vbi_teletext_packet(), stored in the Teletext page cache, and
* formatted by vbi_format_vt_page() creating a vbi_page. It is
* thus not directly accessible by the client. Note the size
* (of the union) will vary in order to save cache memory.
**/
typedef struct vt_page {
/**
* Defines the page function and which member of the
* union applies.
*/
page_function function;
/**
* Page and subpage number.
*/
vbi_pgno pgno;
vbi_subno subno;
/**
* National character set designator 0 ... 7.
*/
int national;
/**
* Page flags C4_ERASE_PAGE ... C11_MAGAZIN_SERIAL.
*/
int flags;
/**
* One bit for each LOP and enhancement packet
*/
int lop_lines;
int enh_lines;
union {
struct lop {
unsigned char raw[26][40];
pagenum link[6 * 6]; /* X/27/0-5 links */
vbi_bool flof, ext;
} unknown, lop;
struct {
struct lop lop;
enhancement enh;
} enh_lop;
struct {
struct lop lop;
enhancement enh;
vt_extension ext;
} ext_lop;
struct {
uint16_t pointer[96];
vt_triplet triplet[39 * 13 + 1];
// XXX preset [+1] mode (not 0xFF) or catch
} gpop, pop;
struct {
uint8_t raw[26][40];
uint8_t bits[48][12 * 10 / 2];
uint8_t mode[48];
uint64_t invalid;
} gdrcs, drcs;
ait_entry ait[46];
} data;
/*
* Dynamic size, add no fields below unless
* vt_page is statically allocated.
*/
} vt_page;
/**
* @internal
* @param vtp Teletext page in question.
*
* @return Storage size required for the raw Teletext page,
* depending on its function and the data union member used.
**/
static inline int
vtp_size(vt_page *vtp)
{
switch (vtp->function) {
case PAGE_FUNCTION_UNKNOWN:
case PAGE_FUNCTION_LOP:
if (vtp->data.lop.ext)
return sizeof(*vtp) - sizeof(vtp->data) + sizeof(vtp->data.ext_lop);
else if (vtp->enh_lines)
return sizeof(*vtp) - sizeof(vtp->data) + sizeof(vtp->data.enh_lop);
else
return sizeof(*vtp) - sizeof(vtp->data) + sizeof(vtp->data.lop);
case PAGE_FUNCTION_GPOP:
case PAGE_FUNCTION_POP:
return sizeof(*vtp) - sizeof(vtp->data) + sizeof(vtp->data.pop);
case PAGE_FUNCTION_GDRCS:
case PAGE_FUNCTION_DRCS:
return sizeof(*vtp) - sizeof(vtp->data) + sizeof(vtp->data.drcs);
case PAGE_FUNCTION_AIT:
return sizeof(*vtp) - sizeof(vtp->data) + sizeof(vtp->data.ait);
default:
;
}
return sizeof(*vtp);
}
/**
* @internal
*
* TOP BTT page class.
*/
typedef enum {
BTT_NO_PAGE = 0,
BTT_SUBTITLE,
BTT_PROGR_INDEX_S,
BTT_PROGR_INDEX_M,
BTT_BLOCK_S,
BTT_BLOCK_M,
BTT_GROUP_S,
BTT_GROUP_M,
BTT_NORMAL_S,
BTT_NORMAL_9, /* ? */
BTT_NORMAL_M,
BTT_NORMAL_11 /* ? */
/* 12 ... 15 ? */
} btt_page_class;
/**
* @internal
*
* Enhancement object type according to ETS 300 706, Section 12.3.1,
* Table 28: Function of Row Address triplets.
*/
typedef enum {
LOCAL_ENHANCEMENT_DATA = 0,
OBJ_TYPE_NONE = 0,
OBJ_TYPE_ACTIVE,
OBJ_TYPE_ADAPTIVE,
OBJ_TYPE_PASSIVE
} object_type;
/**
* @internal
*
* MOT default, POP and GPOP object address.
*
* n8 n7 n6 n5 n4 n3 n2 n1 n0
* packet triplet lsb ----- s1 -----
*
* According to ETS 300 706, Section 12.3.1, Table 28
* (under Mode 10001 - Object Invocation ff.)
*/
typedef int object_address;
typedef struct {
int pgno;
ext_fallback fallback;
struct {
object_type type;
object_address address;
} default_obj[2];
} vt_pop_link;
typedef struct {
vt_extension extension;
uint8_t pop_lut[256];
uint8_t drcs_lut[256];
vt_pop_link pop_link[16];
vbi_pgno drcs_link[16];
} vt_magazine;
struct raw_page {
vt_page page[1];
uint8_t drcs_mode[48];
int num_triplets;
int ait_page;
};
/* Public */
/**
* @ingroup HiDec
* @brief Teletext implementation level.
*/
typedef enum {
VBI_WST_LEVEL_1, /**< 1 - Basic Teletext pages */
VBI_WST_LEVEL_1p5, /**< 1.5 - Additional national and graphics characters */
/**
* 2.5 - Additional text styles, more colors and DRCS. You should
* enable Level 2.5 only if you can render and/or export such pages.
*/
VBI_WST_LEVEL_2p5,
VBI_WST_LEVEL_3p5 /**< 3.5 - Multicolor DRCS, proportional script */
} vbi_wst_level;
/* Private */
struct teletext {
vbi_wst_level max_level;
pagenum header_page;
uint8_t header[40];
pagenum initial_page;
vt_magazine magazine[9]; /* 1 ... 8; #0 unmodified level 1.5 default */
int region;
struct page_info {
unsigned code : 8;
unsigned language : 8;
unsigned subcode : 16;
} page_info[0x800];
/*
* Property of cache.c in the network context:
* 0: page not cached, 1-3F80: highest subno + 1
*/
uint16_t cached[0x800];
pagenum btt_link[15];
vbi_bool top; /* use top navigation, flof overrides */
struct raw_page raw_page[8];
struct raw_page *current;
};
/* Public */
/**
* @addtogroup Service
* @{
*/
extern void vbi_teletext_set_default_region(vbi_decoder *vbi, int default_region);
extern void vbi_teletext_set_level(vbi_decoder *vbi, int level);
/** @} */
/**
* @addtogroup Cache
* @{
*/
extern vbi_bool vbi_fetch_vt_page(vbi_decoder *vbi, vbi_page *pg,
vbi_pgno pgno, vbi_subno subno,
vbi_wst_level max_level, int display_rows,
vbi_bool navigation);
extern int vbi_page_title(vbi_decoder *vbi, int pgno, int subno, char *buf);
/** @} */
/**
* @addtogroup Event
* @{
*/
extern void vbi_resolve_link(vbi_page *pg, int column, int row,
vbi_link *ld);
extern void vbi_resolve_home(vbi_page *pg, vbi_link *ld);
/** @} */
/* Private */
/* packet.c */
extern void vbi_teletext_init(vbi_decoder *vbi);
extern void vbi_teletext_destroy(vbi_decoder *vbi);
extern vbi_bool vbi_decode_teletext(vbi_decoder *vbi, uint8_t *p);
extern void vbi_teletext_desync(vbi_decoder *vbi);
extern void vbi_teletext_channel_switched(vbi_decoder *vbi);
extern vt_page * vbi_convert_page(vbi_decoder *vbi, vt_page *vtp,
vbi_bool cached, page_function new_function);
extern void vbi_decode_vps(vbi_decoder *vbi, uint8_t *p);
/* teletext.c */
extern vbi_bool vbi_format_vt_page(vbi_decoder *, vbi_page *,
vt_page *, vbi_wst_level max_level,
int display_rows, vbi_bool navigation);
#endif
syntax highlighted by Code2HTML, v. 0.9.1