|
2017/08/25(Fri) 13:48:37 編集(投稿者)
■No84945 (ag さん) に返信 > 出力される内容が圧縮前と同じ内容になってしまい
データに問題があるか(無圧縮データだったとか)、 展開コードに問題があるかのいずれかだと思います。
> 圧縮された画像データを解凍する関数になります。
ushort は 256 以上の値を扱えますが、byte はそうではないですよね。 「同じ」ということは、lzw に 255(0xFF) を超える値が無かったということでしょうか。
LZW ということは、初期データは 0〜255 だとしても、文字列が長くなれば、 256 以降のコードも順次追加されていくと思います。 辞書も渡す場合はこの閾値も変化しますが、今回の初期辞書は固定ですよね。
そして引数 lzw 内に 0〜255 の範囲のコードしか含まれていないのであれば それは非圧縮データなので、展開後も同じデータになるはずです。 辞書がスライドされている場合は別として。
> // 辞書の初期化 > dic = new System.Collections.ArrayList(); 初期辞書は、258 パターンの文字列をセットしたものなのですね。 ("00"〜"FF" の 256 種に、"CLEAR" と "END" の 2 種を加えたもの)
ところで、何故ジェネリックコレクションを使わないのでしょうか。 ArrayList だと object 型でしか扱えないので、 毎回 ToString することになり、効率が悪そうに思うのですが。
> ですが、出力される内容が圧縮前と同じ内容になってしまい、原因が分からない状態です。 クリアコードと終了コードがまったく処理されていないようですが、含まれない前提でしょうか?
たとえばクリアーコードが来た場合は、辞書を初期時状態にリセットする必要があるはずですが、 現在はそれがないので、コード 256 が渡されてきた場合、ArgumentException で中断されてしまうと思います。
エンコード側がクリアーコードや終了コードを使わない仕様なのだとしたら、 初期辞書にそれを含めておく必要があるかどうかを再確認してください。
もし含まれる仕様なのであれば、デコード部にはそのための処理も 記述するべきかと思います。
たとえば提示いただいたコードに対して ushort[] lzw = { 84, 65, 258, 71, 259, 67, 84, 258, 259, 266 }; なデータを渡してみると、展開結果は byte[] result = { 84, 65, 84, 65, 71, 65, 84, 67, 84, 84, 65, 65, 84, 65, 84, 65}; になりますね。256 以上の部分が展開されていることが分かると思います。
もしも、クリアコードと終了コードを含まない辞書の場合には、 その 2 つ分だけ、258→256、259→257 のようにコードがずれるので、 ushort[] lzw = { 84, 65, 256, 71, 257, 67, 84, 256, 257, 264 }; を渡したときに、上記と同じ変換結果が得られる仕組みです。
|