パスワードを忘れた? アカウント作成
432801 journal

asatakuの日記: khtmlの日本語自動認識部解説

日記 by asataku

kzkさんの日記の関連で、khtmlの日本語自動認識部の簡単な解説を。
ついでに考えている最中に見つけた問題点も。

なお、バージョンはKDE-3.1.Xのkdelibs/khtml/misc/decoder.cppを用いる。
日本語の自動認識はKDE-3以降なら入っている機能ではあるが、バージョンによる認識アルゴリズムの差はないはずである。
ただし、KDE-3.2では認識ルーチンが動作するための条件が変化する予定である。

実際の認識用ルーチンは KanjiCode::judge() であるが、これはjvimのソースコードから流用した物である。
認識精度、コード量などを考慮して、Unicode関連の認識ルーチンは削除したがアルゴリズム自体は変えてない。
このルーチンでは与えられた文字列に対して、それがASCII, EUC, SJISのどれであるかを判定している。
これに関する詳細は割愛。コードを見てください。

認識用ルーチンを呼び出している部分のコードは以下のようになっている。(改行等は変更)

if (!haveEncoding && KGlobal::locale()->languageList()[0] == "ja") {
        switch ( KanjiCode::judge( data ) ) {
        case KanjiCode::JIS: enc = "jis7"; break;
        case KanjiCode::EUC: enc = "eucjp"; break;
        case KanjiCode::SJIS: enc = "sjis"; break;
        default: enc = NULL; break;
}
if (!enc.isEmpty()) { setEncoding(enc, true); }

一行目のif文の条件から分かるように、利用言語の一番始めが日本語であることが自動認識が動作する条件である。
KDE-3.2では言語の認識系の動作条件が変更になったため、khtmlの自動認識対象を日本語に設定してあれば日本語の自動認識が動作するようになる。

また、htmlやhttpの段階でcharsetが指定されている場合にはhaveEncodingが設定されるため、自動認識は行なわれない。

dataにはkhtmlが読み込んだブロックが生のまま入っている。
dataの長さが幾つかは不定である。その時々の回線などの状況によって変化すると考えていただきたい。
(自動認識部のデバッグが難しいのはこれがあるためである。必要ルーチンを抜き出して、別に検証用プログラムを作成するのがよい)
KanjiCode::judge()でdataを評価し、その結果どれかの漢字コードだと分かれば setEncoding()を用いて漢字コードを設定する。
setEncoding()を呼び出せばhaveEncodingがtrueとなるため、そのページの以後のデータにおいて、漢字コードの確認、変更は行なわれない。
与えられたデータではコードが認識できなかった場合には次に読み込まれたデータで再度KanjiCode::judge()を呼び出す。

このコードの問題点は境界問題への対処を行なっていない点である。
dataの切れ目が漢字コードやJISのエスケープシーケンスの途中になっていた場合、この自動認識は失敗する可能性がある。
(回線が遅い場合に問題は発生しやすい可能性がある)

それへの対処としては、KanjiCode::judge()で、余りが出た場合にそれを返すようにし、次回の呼び出し時にはその余りも渡してやればよい。

また、自動認識の精度を上げるためにはKanjiCode::judge()の内部状態を構造体にでも格納し、ある程度以上の確度を得られるまでは漢字コードの判断をしないように変更するという手もある。
ただし、この場合には最後まで読み込んだ場合の処理を追加してやる必要がある。
(この修正をする場合にはバイナリコンパチビリティに注意)

というわけで、誰か修正と検証をしてみませんか?

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

UNIXはただ死んだだけでなく、本当にひどい臭いを放ち始めている -- あるソフトウェアエンジニア

読み込み中...