2014-02-26 97 views
0

我有一個奇怪的圖像格式嵌入式設備這裏使用,和往常一樣的文檔是沒有幫助...轉換RGB 444可顯示圖像

下面是文檔的兩行:

該圖像是:

全綵色位圖(4 + 4 +每像素4位),3個字節的每2 像素(從左至右pixelorder)。

因此,爲了能夠得到一個像我們的字節序列中,我已經編寫如下:

// size_x and size_y are known at this point 
QImage img(size_x, size_y, QImage::Format_RGB444); 
int xctr = 0; 
int yctr = 0; 
for(int c1 = 0; c1 < bsize;) // bsize is the size of image bytes 
{ 
    static const int M = 1; // a multiplier to make the image brighter 
    uint8_t b1 = *(p_pos + c1++); // p_pos points to the first image byte 
    uint8_t b2 = *(p_pos + c1++); 
    uint8_t b3 = *(p_pos + c1++); 

    uint8_t pix1_r =((b1 & 0xF0) >> 4) * M; 
    uint8_t pix1_g =((b1 & 0xF)) * M; 
    uint8_t pix1_b =((b2 & 0xF0) >> 4) * M; 

    uint8_t pix2_r =((b2 & 0xF)) * M; 
    uint8_t pix2_g =((b3 & 0xF0) >> 4) * M; 
    uint8_t pix2_b =((b3 & 0xF)) * M; 

    // old code 
    //unsigned int pix1 = pix1_r << 8 | pix1_g << 4 | pix1_b; 
    //unsigned int pix2 = pix2_r << 8 | pix2_g << 4 | pix2_b; 

    // new code 
    unsigned int pix1 = ((unsigned int)pix1_r) << 8 | pix1_g << 4 | pix1_b; 
    unsigned int pix2 = ((unsigned int)pix2_r) << 8 | pix2_g << 4 | pix2_b; 

    // set the first pixel 
    img.setPixel(xctr, yctr, pix1); 
    xctr ++; 
    if(xctr == size_x) { 
     xctr = 0; 
     yctr ++; 
    } 

    // set the second pixel 
    img.setPixel(xctr, yctr, pix2); 
    xctr ++; 
    if(xctr == size_x) { 
     xctr = 0; 
     yctr ++; 
    } 
} 

這裏是我得到從這個結果的圖像:

My image

這裏是一個圖像(非常相似,)我應該得到(只有藍色/紅色的部分,請不要考慮黑色的背景和雪:)):

What I expect

對於膽大的,圖像數據:http://pastebin.com/m4y8qamB請隨時使用這個Python creating an array from hex bytes原始數據爲「真正的」十六進制字節轉換。

問題:現在,忽略嵌入設備本身的圖像調色板,我錯誤地做了什麼,我沒有獲得與預期類似的圖像?我應該怎麼做才能獲得類似的圖像?

編輯將解碼值(和印刷字符)的一些打印完成後,我得到的是這樣的:

PPPPPPPPPPPPPPPPPPPAPPPPPPPPPPPP 
PPPPPPPAPPPPPPPPPPPPPPPPPPPAPPPP 
PPPPPPPPPPPPPPPAPPPPPPPPPPPPPPPP 
PPPAPPPPPPPPPPPPPPPPPPPAPPPPPPPP 
PPPPPPPPPPPAPPPPPPPPPPPPPPPPPPPA 
PPPPPPPPPPPPPPPPPPPAPPPPPPPPPPPP 
PPPPPPPAPPPPPPPPPPPPPPPPPPPAPPPP 
PGPPPPPPPPPPPPPAPPPPPCANMMMMMMMM 
MMMMAMMMMOPCALDDDDDDDDDDDADDDMPC 
ANODDDDDDDDDDDDADDKPANPCAGMMMMMM 
MMMMMMAMMNPCANPCANPCANPCANPCANPC 
ANPCANPPPAPPANPCANPCANPCANPCANPC 
ANPCANPCADDADDPCANPCANPCANPCANPC 
ANPCANPCANPCMMAMMMMMMMMMMMMMMMMM 
MMAMMMMMMMMMMMMMMMMMMMAMMMMMMMMM 
MMMMMMMMMMAMMMMMMMMMMMMMMMMMMMAM 
MMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMM 
MMMMMMAMMMMMMMMMMMMMMMMMMMAMMMMM 
MMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMM 
MMAMMMMMMMMMMMMMMMMMMMAMMMMMMMMM 
+0

您是否檢查過size_x和size_y,如果它們正常?這個結果看起來像比原來的比例有所不同。 –

+0

在'pix1_r << 8','pix1_r'是8位變量,做8位移位將使其零,我建議你把它強制轉換爲16位或32位。 –

+0

它們也與圖像字節一起編碼在圖像數據中(請參閱pastebin)。我一直沒有使用方形像素的感覺,原來,因爲它是33x18) – fritzone

回答

2

我轉換引擎收錄數據使用的二進制文件

perl -pe 's/([0-9a-f]{2})\s+/chr(hex($1))/ige' > tempfile 

這看起來是正確的,當我看着該文件的十六進制轉儲。

然後我寫了一個程序來解碼該文件:

#include <stdio.h> 

    typedef unsigned char uint8_t; 
    #define M 1 

    int main(void) { 
      FILE *fp; 

      int sizex, sizey; 
      int xctr, yctr; 
      int i=0; 

      if ((fp=fopen("tempfile", "rb"))==NULL) { 
        perror("tempfile"); exit(1); 
      } 
      sizey=getc(fp); 
      sizex=getc(fp); 
      int bsize=getc(fp)*256; 
      bsize+=getc(fp); 

      xctr=yctr=0; 
      for (i=0; i<bsize/3; i++) { 
        uint8_t b1=getc(fp); 
        uint8_t b2=getc(fp); 
        uint8_t b3=getc(fp); 

        uint8_t pix1_r =((b1 & 0xF0) >> 4) * M; 
        uint8_t pix1_g =((b1 & 0xF)) * M; 
        uint8_t pix1_b =((b2 & 0xF0) >> 4) * M; 

        uint8_t pix2_r =((b2 & 0xF)) * M; 
        uint8_t pix2_g =((b3 & 0xF0) >> 4) * M; 
        uint8_t pix2_b =((b3 & 0xF)) * M; 

        unsigned int pix1 = ((unsigned int)pix1_r) << 8 | pix1_g << 4 | pix1_b; 
        unsigned int pix2 = ((unsigned int)pix2_r) << 8 | pix2_g << 4 | pix2_b; 

        printf("%3x ", pix1); 
        xctr++; 
        if (xctr==sizex) { 
          putchar('\n'); 
          xctr=0; 
        } 
        printf("%3x ", pix2); 
        xctr++; 
        if (xctr==sizex) { 
          putchar('\n'); 
          xctr=0; 
        } 
      } 
    } 

這確實或多或少你做什麼,並具有輸出:

393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 
    393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 
    393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 
    393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 
    393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 
    393 393 393 393 393 393 393 999 ddd eee bcc 393 393 999 fd0 2fd 02f d02 fd0 2f9 993 933 933 933 939 99f fd0 2fd 
    02f d02 fd0 2fd 02f ccc 666 ffd 02f d02 fd0 2fd 02f d02 fd0 2fd 029 993 933 933 93d ddf fd0 2fd 02f d02 fd0 2fd 
    02f d02 fd0 2ee eff d02 fd0 2fd 02f d02 fd0 2fd 02f d02 ddd 393 393 393 fd0 2fd 02f d02 bbb 393 bcc ffd 02f d02 
    fd0 1ee 393 393 bbb ffd 02f d02 f39 339 339 3fd 02f d02 fd0 239 339 339 3ee efd 02f 999 393 393 393 ffd 02f d02 
    f39 339 339 3fd 02f d02 fd0 2aa a39 399 9ff d02 fd0 2fd 01e e39 339 399 9ff d02 fd0 2f3 933 933 93d ddf fd0 2fd 
    02f d02 fd0 2fd 02f d02 fd0 2fd 02f d02 fd0 2fd 02f d01 eef d02 fd0 2fd 02d dd3 933 933 938 88f fd0 2fd 02f d02 
    fd0 2fd 02f aaa 999 ffd 02f d02 fd0 2fd 02f d02 fd0 2fd 029 993 933 933 933 938 88c ccc cc9 993 933 93a aaf d02 
    fd0 2fd 02f d02 f99 939 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 
    339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 
    339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 
    339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 

這似乎是在解碼過程是確定,但輸出仍然不像圖像。

再次查看您的原始pastebin數據,我幾乎可以肯定這個數據有一些錯誤。在開始時,序列'39 33 93'重複幾次,很好地轉換爲393 393.但是稍後,您有'FD 02 FD 02 FD 02 FD 02'。這將轉化爲'FD0 2FD 02F D02 FD0 2 ..',我無法想象這是正確的。是否有可能丟失了一些字節(比如\ 0字節沒有被傳輸),結尾的339實際上是屬於下一個圖像的數據?

+0

嗯更新,謝謝大家的努力。我也得到了這樣的結論,如果沒有什麼隱藏在圖像格式的描述(沒有發現任何),那麼必然在數據中是錯誤的......現在在另一端有一個「有效」的圖像(取自一個真實的總線),其中相同的數據很好地解碼成我們所看到的......所以我有這樣的感覺,解碼算法中有一些是在總線上實現的硬件,但沒有記錄:( – fritzone

1

我不能讓這個問題休息;)我發現我的文件有2F7(十六進制)字節,但頭說02A0,所以必須有東西是在文件中,但對輸出到被忽略。然後,我想到了如果從輸入中忽略所有'F'半字節(並且從輸出中省略了393)會發生什麼情況,但是結果看起來並不太好,特別是有時會轉移39 33 93解碼933 933 933

接下來,我省略了所有的F和E半字節,導致此:


start of image 









       999 ddd bcc   999 d02 d02 d02 d02 999 
      999 d02 d02 d02 d02 d02 ccc 666 d02 d02 d02 d02 d02 d02 
    d02 999    ddd d02 d02 d02 d02 d02 d02 d02 d02 d02 d02 
    d02 d02 d02 d02 ddd    d02 d02 d02 bbb  bcc d02 d02 
    d01   bbb d02 d02    d02 d02 d02    d02 
    999    d02 d02    d02 d02 d02 aaa  999 d02 
    d02 d01   999 d02 d02    ddd d02 d02 d02 d02 d02 
    d02 d02 d02 d02 d02 d02 d01 d02 d02 d02 ddd    888 d02 
    d02 d02 d02 d02 aaa 999 d02 d02 d02 d02 d02 d02 d02 999 
      888 ccc ccc 999   aaa d02 d02 d02 d02 999 









    I'm now at 02df 
    end of image 

看起來並不完全正確的,但要好得多比迄今爲止所有的東西都要好。我認爲還有一些東西需要省略,因爲代碼讀取的時間是0x2df,而不是0x2f7,但也許這可以幫助你找到你需要做的事情。這是我的代碼;注意我首先閱讀sizey,然後sizex,因爲這看起來會產生更好的圖片:

#include <stdio.h> 

    typedef unsigned char uint8_t; 
    #define M 1 

    int sizex, sizey; 
    int xctr, yctr; 

    int main(void) { 
      FILE *fp; 

      int i=0, c; 
      int flag; 

      if ((fp=fopen("tempfile", "rb"))==NULL) { 
        perror("tempfile"); exit(1); 
      } 
      sizey=getc(fp); 
      sizex=getc(fp); 
      int bsize=getc(fp)*256; 
      bsize+=getc(fp); 

      xctr=yctr=0; 
      for (i=0; i<bsize*2;) { 
        c=getc(fp); 
        if ((c&0xf0) != 0xf0 && (c&0xf0) != 0xe0) { 
          push ((c>>4)&0x0f); 
          i++; 
        } 
        if ((c&0x0f) != 0x0f && (c&0x0f) != 0x0e) { 
          push (c&0x0f); 
          i++; 
        } 

      } 
      printf("I'm now at %04x\n", ftell(fp)); 
    } 


    int push(int c) { 
      static int pos=0; 
      static uint8_t red, green, blue; 

      if  (pos==0) { pos=1; red=c; } 
      else if (pos==1) { pos=2; green=c; } 
      else if (pos==2) { pos=0; blue=c; } 

      if (pos==0) { 
        if (red==3 && green==9 && blue==3) 
          printf(" "); 
        else 
          printf("%01x%01x%01x ", red, green, blue); 
        xctr++; 
        if (xctr==sizex) { 
          putchar('\n'); 
          xctr=0; 
        } 
      } 
    } 
+0

嗯,這似乎很有希望:)再次感謝你的努力。 – fritzone