-128 ????

昨日までの結果で、画像の柄は復元できているっぽいのに、
色味が変なので、YCbCr⇒RGB の変換がミスっているっぽい。

変換式は間違ってないと思うけど・・

R = Y + 1.40200 × Cr (V)
G = Y - 0.34414 × Cb (U) - 0.71414 × Cr (V)
B = Y + 1.77200 × Cb (U)

(※↑変換式としては正しいですが、JPEG的には間違っています)


・・・!!!!


JFIFの仕様書に、

R = Y + 1.402 (Cr-128)
G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
B = Y + 1.772 (Cb-128)

128ってなんだぁぁぁぁぁ!


そもそも、RGB⇒YCbCrの変換の時に、+128しているようです。
それは、YCbCrにした時に正の値のみで表現できるようにする為のようです。(符号ビットがモッタイナイのかな?)



という事で、色味が綺麗に復元できるようになりました。


テスト画像

修正前

修正後


次は、縦縞ですね☆

直りま

せんでした・・・・

でも、進展はありました^^

0xFF の後の 0x00 をスキップする処理がバグっており(汗
一度スキップしてしまうと、その後、永遠と1byte読み込むと1byteスキップするという、
マヌケな事になっていました。(アハハ

(フラグを立てて、0x00を華麗にスルーしたのは良いけれど、フラグ立てっぱなしで、スルーしまくり(笑))


テストデータ


修正前



修正後



この修正後のデータは、だいぶ、元の画像に近くなってきました☆
うっすらですが、前の画像の模様が見えます!!


まぁ、まだまだですよね(アハハ


                                                        • -

【豆知識】

JPEGにおいては、0xFF (2進数で表すと:11111111)という値は特別な値で、決められた所にした使用出来ません。
(0xFFは、マーカーというものの開始を表します。)

ここで、JPEGはデータをbit単位で圧縮しますので、

・・・001101110101010101・・・・と並んで行き、

時として

・・・11111111・・・・・ となってしまう事があります。

これが、運悪く、あるbyteの0番目から始まると、0xFF(11111111)となってしまいます。


そこで、圧縮データ中に偶然 0xFF が出来てしまった場合には、圧縮データとは関係なく、その次に 0x00 を入れて、
この 0xFF が偶然のものであるという事を示します。


そこで、デコーダーは、0xFFを発見したら、次のバイトが0x00なら、その0x00は存在しないものとして、
その次のbyteから続きの処理をします。

AC成分の復号

Jpegは、8x8ピクセル毎に圧縮しています。

一応、8x8の1ブロックを復号する処理まで書いたのですが、どうもバグっていて、全然前に進みません。
どこが間違っているのか、やっと分かったので書いておきます。


ハフマン符号化されたデータは、

bit列で、
[HuffmanCode][HuffmanValue][HuffmanCode][HuffmanValue]・・・・と並んでいます
011110100101010101010101010101010101011111・・・・・・・・

DC成分は、HuffmanCodeをデコードすると、HuffmanValueの長さを示します。HuffmanValueは、DCTの係数値の差分を示しています。
AC成分は、HuffmanCodeをデコードすると、前半4byteはランレングスで、後半4byteがHuffmanValueの長さを示してます。

・・・・・

てっきり、
AC成分は、HuffmanCodeをデコードすると、HuffmanValueの長さを示していて、
HuffmanValueの前半4byteはランレングスで、後半4byteがDCTの係数値だと思ってましたよ(涙)


※複合化した値が、やたらと 0 ばっかりになる人は、一度確認してみて下さい(笑
(今更JPEGのデコードなんてしてる人いないか・・・)


[追記]
ああ・・・

逆DCTも、値が変・・・・

[追記2]
ああ・・・

√2じゃなくて、1/√2 でした・・・

このブログは

JPEGデコーダーを、C言語で作成してみるブログです。

そして、DCT(離散コサイン変換)を、ただ"波形の係数に変換してる"みたいな説明以上に理解してみたいと思っています。

そのうち、ソースをアップします。

それでは、宜しくお願いします。