やっとデコードの準備が整いました。実データのデコードに入ります。
JPEGでは0xFFはマーカーの意味合いがあるため、実データで0xFFを用いるときは、その後ろに必ず0x00をつけてやる必要があります。
またRSTのようなマーカーが途中にある場合は、その規定に従わなければなりません。ただCR2内のLossless JPEGは、
終端の0xFFD9まで途中にマーカーがあることなくエンコードされている様子ですので、ここでもその前提でデコードします。
それでは実際にデコードしていきます。
前述したとおり、0xFF 0x00 の並びは単なる0xFFを意味するので、実際のデータ列は
0xFF 0x00 0xFF 0xFC 0x00 0xEF 0xF7 0x00 0x3F 0x98 0xC7 ......
となります。
エンコード/デコードのルールの概要は以下の通りです。
初期値は2の(ビット精度-1)乗からスタートします。サンプルでは2の13乗なので、0x2000 (8192)です。
最初の1行目の予測アルゴリズムは必ず1番を使います。すなわち左の値との差分が記録されています。
今回はPredictorは1ですので、すべての行でこのアルゴリズムを使用します。
改行した場合の最初の値のアルゴリズムは必ず2番を使います。つまり上の値との差分が記録されます。
それでは最初の6byteをbit表示してデコードしてみます。
1111 1111 0000 0000 1111 1111 1111 1100 0000 0000 1110 1111
コンポーネント番号1からはじめます。
コンポーネント番号1のDCハフマンテーブルは0ですので、それを参照します。
上位bitから照合していき、葉にたどり着く値を取得します。
この場合は 1111 1111 0 が該当します。
1111 1111 0 000 0000 1111 1111 1111 1100 0000 0000 1110 1111
ハフマンテーブルから、値は0x0Dです。
次に、先ほど取得した0x0D=13bit分の値をデータ列から取得します。
1111 1111 0000 0000 1111 1111 1111 1100 0000 0000 1110 1111
取得した値の最上位ビットが0の場合は、負数を意味しますので、ビット反転させた値を前の値から引き算します。
111 1111 0000 00 =0x1FC0 (8128)なので、8192 - 8128 = 64 (0x0040)になります。
なお最上位ビットが1の場合はその値をそのまま加算すればOKです。
なお、この部分は以下のようにも計算できます。
取得した値の最上位ビットが0の場合は負数と判断し、まず全体に1を加算します。
000 0001 0000 00
値を16bit長とし、不足する上位ビットを1で埋めます。
111 000 0001 0000 00
16bit長の2の補数表現として値を扱います。
値は-8128になりますので、前の値8192に加算して 64 (0x0040)を得ます。
続けてコンポーネント番号2を計算します。
コンポーネント番号2のDCハフマンテーブルは1ですので、それを参照します。
コンポーネント番号1の続きから、上位bitから照合していき、葉にたどり着く値を取得します。
この場合は 1111 1111 0 が該当します。
1111 1111 0000 0000 1111 1111 1111 1100 0000 0000 1110 1111
ハフマンテーブルから、値は0x0Dです。
次にここで取得した0xD=13bit分の値を取得します。
1111 1111 0000 0000 1111 1111 1111 1100 0000 0000 1110 1111
取得した値の最上位ビットが0ですので、上記と同様に値を取得します。
値は-8177になりますので、前の値である初期値8192に足します。
結果値は15 (0x000F) が得られます。
ここでこれらの値の正しさを確認してみます。
以下はこのCR2ファイルを非圧縮でDNGに変換し、RAWデータ部分を切り出したものです。
(IMG_2026_RAW_Data_from_DNG.bin 参照)
確かに最初の2byteが0x0040、次の2byteが0x000Fとなっています。(リトルエンディアンです)
この後コンポーネント番号3番および4番に対応する値をそれぞれ計算します。
それが終われば再びコンポーネント番号1番を計算します。その場合前回算出した値である(0x0040)との差分が記録されていますので
得られた値と0x0040を加算することで、値を求めます。
あとはこれの繰り返しです。
改行した際は前述の通り、上の値との差分が記録されていますので、それに応じて算出します。
なお先ほど照合に使ったDNGから抽出したデータと、LosslessJPEGから抽出した値はあるポイントから後ろは合致しません。
IFD3の項目で記述したcr2_sliceの配置があるためです。
実際の画像センサーの配列と同じようにするためには、このcr2_sliceの並び替えを行なう必要があります。
Lossless JPEGをデコードした直後のデータは以下の図のようになっています。
これを下図のように並べ替えます。
この並び替えで、画像センサーの配列と同じRAWデータが取得できます。
ここから実画像を取得するには、実効画素範囲の情報から、それを抜き出し処理します。
(おわり)
前のページ
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]