TSパケットからはじめる(4) - 文字コード1

文字コード概要

TSパケットは独自フォーマット形式の文字コードが格納されています。独自と言ってもEUCJPを拡張したような構造です。PSIのSDTやEITを取り扱う上で文字コード変換が必要になるため、このタイミングとなります。

ARIB STD-24概要図

G0、G1、G2、G3という領域がそこには図形表(例えば"漢字")を割り当てすることができます。GL/GRからはG0~G3を参照します。GL/GRからG0~G3を経由して図形表からデータを取り出すことができます。

例えば、GLは現在G0を参照していますが、GLの参照先をG1にするとGLは結果としてアルファベットを参照することになります。変換するコードが

0x41 0x42 0x43だった場合には0x41はGLコード範囲となるのでGLはアルファベット表は参照しており、これはASCIIコードとして0x41はA、0x42はB、0x43はCとなります。また、GLがG1を参照することをLS1と呼びます。

もしGRがアルファベットを参照していた場合には、0x41、0x42、0x43は0xC1、0xC2、0xC3という値が入っているはずです。GR経由の場合は先頭ビットを0にして図形表を参照します。先頭ビット以外の値を取得するので0x7Fでアンドを取るという意味です。0xC1 & 0x7F = 0x41

字幕データの場合は色や表示位置、表示時間等、考慮しなければならないことがたくさんありますが単純に文字コード変換だけであれば非常にシンプルです。

文字コードと制御コード

文字コードの1バイトでどのコード範囲かを判断します。GLは0x21~0x7F範囲、GRは0xA0~0xFEまでとなります。C0とC1という制御コードがあります。

1バイト目のコード範囲

今回出てくるのはほとんどC0となります。C1には字幕系の制御コードが多数含まれています。

Designation処理

G0からG3に図形表を指定する処理となります。0x1BはESCの意味ですが、以下のような文字列に対して処理をします。

0x1B 0x28 xxx: 1バイトのxxxテーブル番号をG0に割り当て
0x1B 0x29 xxx: 1バイトのxxxテーブル番号をG1に割り当て
0x1B 0x2A xxx: 1バイトのxxxテーブル番号をG2に割り当て
0x1B 0x2B xxx: 1バイトのxxxテーブル番号をG3に割り当て

0x1B 0x24 xxx: 2バイトのxxxテーブル番号をG0に割り当て
0x1B 0x24 0x29 xxx: 2バイトのxxxテーブル番号をG1に割り当て
0x1B 0x24 0x2A xxx: 2バイトのxxxテーブル番号をG2に割り当て
0x1B 0x24 0x2B xxx: 2バイトのxxxテーブル番号をG3に割り当て

0x1B 0x28 0x20 xxx: 1バイトのxxxDRCSテーブル番号をG0に割り当て
0x1B 0x29 0x20 xxx: 1バイトのxxxDRCSテーブル番号をG1に割り当て
0x1B 0x2A 0x20 xxx: 1バイトのxxxDRCSテーブル番号をG2に割り当て
0x1B 0x2B 0x20 xxx: 1バイトのxxxDRCSテーブル番号をG3に割り当て

0x1B 0x24 0x28 0x20 xxx: 2バイトのDRCSxxxテーブル番号をG0に割り当て
0x1B 0x24 0x29 0x20 xxx: 2バイトのDRCSxxxテーブル番号をG1に割り当て
0x1B 0x24 0x2A 0x20 xxx: 2バイトのDRCSxxxテーブル番号をG2に割り当て
0x1B 0x24 0x2B 0x20 xxx: 2バイトのDRCSxxxテーブル番号をG3に割り当て

Invocation処理

GLとGRがG0、G1、G2、G3を参照処理です。

LS0(0x0F): G0をGLに割り当て
LS1(0x0E): G1をGLに割り当て
LS1R(0x1B 0x7E): G1をGRに割り当て
L2(0x1B 0x6E): G2をGLに割り当て
L2R(0x1B 0x7D): G2をGRに割り当て
L3(0x1B 0x6F): G3をGLに割り当て
L3R(0x1B 0x7C):G3をGRに割り当て
SS2(0x19): G2をGLに一時的に割り当て
SS3(0x1D):G3をGLに一時的に割り当て

SS2とSS3は一時的にGLを割り当てするのでSingle Shiftと呼ばれ、それ以外は継続的に割り当てするのでLocking Shiftと呼ばれます。割り当てを1文字つづ変えないといけない状況では制御コードで溢れてしますので1文字分だけ一時的に割り当てすることを可能にしています。

図形表のコード番号とバイト数

図形表一覧は以下になります。

  • 1byteの図形表

0x4A: Alphanumerical
0x30: Hiragana
0x31: Katakana
0x32: Mosaic A
0x33: Mosaic B
0x34: Mosaic C
0x35: Mosaic D
0x36: Proportional alphanumeric
0x37: Proportional hiragana
0x38: Proportional katakana
0x41 – 0x4F: DRCS-1〜15
0x70: Macro-code

  • 2byteの図形表

0x42: Kanji
0x39: JIS compatible Kanji Plane 1
0x3A: JIS compatible Kanji Plane 2
0x3B: Additional symbols
0x40: DRCS-0

 先頭の数字はその表番号を意味しています。

文字コードサイズ

C1制御コードに含まれますが文字サイズを意味する制御コードがあります。
SSZ(0x88): Small Size
MSZ(0x89): Middle Size
NSZ(0x8A): Normal Size(初期値)

SSZはEIT等では出てこないのですがMSZ、NSZは使用されます。意味合いとしては全角、半角のような取り扱いをしています。NSZは全角、MSZは半角という感じです。

デコードしてみよう

ここまでわかればデコードできるはずです。

aa b3 c8 ef ea

初期状態は以下になります。
G0: Kanji
G1: Alphanumeric
G2: Hiragana
G3: Katakana

GL: G0が割り当て
GR: G2が割り当て

文字サイズ: NSZ

0xaa: GR領域となりG2は平仮名となります。GR領域の場合は先頭ビットを抜かします。0xaa (1010 1010)の先頭ビットを抜かした0x2a(0010 1010)として使用します。平仮名表の0x2aは"お"となります。

0xb3: "こ"
0xc8: "と"
0xef:  "わ"
0xea: "り"

制御コードがないのでそのままですね。

1b 7c b9 bf c3 d5

0x1b 0x7c: 制御コードL3R(G3をGRに割り当て)なので初期値のG3はカタカナをGRに割り当てしています。
0xb9: "ス"
0xbf: "タ"
0xc3: "ッ"
0xd5: "フ"

ちょっと良い例が見つかりませんでしたが、表データと制御コード等を組み込めばデコードすることが可能となりました。

この記事が気に入ったらサポートをしてみませんか?