2017-05-23 10 views
0

現在、私は大学のプロジェクト用のjpegエンコーダを開発中です。イメージのサイズは固定されており、エンコーダはベースライン処理に固定量子化テーブルとハフマンテーブルを使用します。まず、私のコードはSDRAMから32ビットのRGBx値を読み込み、YCbCr色空間に変換し、各チャンネルを0に正規化して書き戻します。その後、8x8ブロックでDCTを開始し、エントロピー符号化データをSDRAMに書き込む。このプロセスはCを使用して行われ、Pythonコードは適切なJFIFマーカーとエントロピー符号化データを含むファイルを作成します。最後に、OSのデフォルトのjpegデコーダは、画像をダブルクリックするだけで見ることができます。画像サイズが16x8または8x16より大きい場合のJPEGエンコーディングエラー

私のコードは、8x8、8x16、16x8イメージで動作しますが、16x16イメージではなく、プロジェクトで使用されるイメージの実際のサイズで動作します。下に16x16の例が表示されます。

16x16 input image 16×16入力、それは私のOSのデフォルトのデコーダに比べてより異なるようですstackoverflowの上

しかし

16x16 output image 16×16出力、。以下は、macOSプレビューアプリケーションでどのように見えるかです。

enter image description here

私は私の問題は、JFIFでマーカーまたはアルゴリズムのエラーのいくつかの種類のいずれかが原因であると考えています。

jpegでの経験があれば誰でも私を助けることができたらとても嬉しいです。

種類は、私はJPEGコーデックを書いた

+0

エンコードされたjpegのバイナリダンプを投稿できますか? (あなたはそれらを16進数にエンコードし、 "貼り付けサイト"またはあなたの質問に投稿することができます) – osgx

+0

https://justpaste.it/171ljこれは私の出力画像の16進数です –

+0

https://justpaste.it/171m3これはjpegファイルを作成するためのPythonコードです –

答えて

0

について。しかし、それはあなたが喜んであなたの質問に答えることはできません、またはそれを使用することを歓迎している間、https://github.com/MalcolmMcLean/babyxrcに維持されます。

JPEGは、輝度の場合は16×16ブロック、輝度の場合は8×8ブロックに基づいています。したがって、最初の16x16ブロック後にソフトウェアの初期バージョンがクラッシュすることは驚くことではありません。これは単なるルーチンプログラミングエラーです。 JEG仕様を読んでも見つからない場合は、エディタを起動してフラットな32x32イメージを作成してください。次に、バイナリを見て、それがあなたと違うところを見てください。

はここでサブサンプリングあなたが見ることができるように

static int loadscanYuv111(JPEGHEADER *hdr, unsigned char *buff, FILE *fp) 
{ 
    short lum[64]; 
    short Cb[64]; 
    short Cr[64]; 
    BITSTREAM *bs; 
    int i; 
    int ii; 
    int iii; 
    int iv; 
    int diffdc = 0; 
    int dcb = 0; 
    int dcr = 0; 
    int actableY; 
    int actableCb; 
    int actableCr; 
    int dctableY; 
    int dctableCb; 
    int dctableCr; 
    int count = 0; 
    int target; 
    int luminance; 
    int red; 
    int green; 
    int blue; 

    actableY = hdr->useac[0]; 
    actableCb = hdr->useac[1]; 
    actableCr = hdr->useac[2]; 
    dctableY = hdr->usedc[0]; 
    dctableCb = hdr->usedc[1]; 
    dctableCr = hdr->usedc[2]; 

    bs = bitstream(fp); 

    for(i=0;i<hdr->height;i+=8) 
    for(ii=0;ii<hdr->width;ii+=8) 
    { 
     if(hdr->dri && (count % hdr->dri) == 0 && count > 0) 
     { 
     readmarker(bs); 
     diffdc = 0; 
     dcb = 0; 
     dcr = 0; 
     } 

     getblock(lum, hdr->dctable[dctableY], hdr->actable[actableY], bs); 
     lum[0] += diffdc; 
     diffdc = lum[0]; 

     for(iv=0;iv<64;iv++) 
     lum[iv] *= hdr->qttable[hdr->useq[0]][iv]; 
     unzigzag(lum); 
     idct8x8(lum); 

     getblock(Cb, hdr->dctable[dctableCb], hdr->actable[actableCb], bs); 
     Cb[0] += dcb; 
     dcb = Cb[0]; 

     for(iv=0;iv<64;iv++) 
     Cb[iv] *= hdr->qttable[hdr->useq[1]][iv]; 
     unzigzag(Cb); 
     idct8x8(Cb); 

     getblock(Cr, hdr->dctable[dctableCr], hdr->actable[actableCr], bs); 
     Cr[0] += dcr; 
     dcr = Cr[0]; 

     for(iv=0;iv<64;iv++) 
     Cr[iv] *= hdr->qttable[hdr->useq[2]][iv]; 
     unzigzag(Cr); 
     idct8x8(Cr); 

     for(iii=0;iii<8;iii++) 
     { 
     if(i + iii >= hdr->height) 
      break; 
     for(iv=0;iv<8;iv++) 
     { 
      if(ii + iv >= hdr->width) 
      break; 
      target = (i + iii) * hdr->width * 3 + (ii + iv) * 3; 
      luminance = lum[iii*8+iv]/64 + 128; 
      red = (int) (luminance + 1.402 * Cr[iii*8+iv]/64); 
      green = (int) (luminance - 0.34414 * Cb[iii*8+iv]/64 - 0.71414 * Cr[iii*8+iv]/64); 
      blue = (int) (luminance + 1.772 * Cb[iii*8+iv]/64); 
      red = clamp(red, 0, 255); 
      green = clamp(green, 0, 255); 
      blue = clamp(blue, 0, 255); 
      buff[target] = red; 
      buff[target+1] = green; 
      buff[target+2] = blue; 
     } 
     } 

     count++; 
    } 

    killbitstream(bs); 
    if(loadeoi(fp) == 0) 
    return 0; 

    return -1; 
} 

、データがインターリーブされるための私のloadscanです。 しかし、それが間違っていると、正しいサイズの特異なイメージが作成され、予想よりも小さいイメージではありません。

+0

chromianceの16x16はデフォルトのサブサンプリングタイプです。 JPEG([4:4:4](https://en.wikipedia.org/wiki/Chroma_subsampling#4:4:4))に "no subsampling"を設定することは可能ですか? – osgx

+0

私はクロミナンスチャネルのサブサンプリングを使用しません。しなければならない? –

+0

サブサンプルするのは正常です。ブロックを正しく設定しないと問題になる可能性があります。 –

関連する問題