2014-08-31 66 views
-2

我有一個關於如何恢復JPG圖像(這是一個CS50的任務)的問題。 我的代碼大部分工作(我相信),但是當我打開找到的JPG文件時,我只收到一堆縮略圖。C. CS50恢復分配,恢復JPG圖像

我一直在試圖解決這個練習很長一段時間,但我似乎無法弄清楚爲什麼它不起作用。有人能幫我推進正確的方向嗎?

這裏是我的代碼(也可在http://pastebin.com/U2pwJd5e):

#include <stdio.h> 
#include <stdlib.h> 

#include "bmp.h" 


int main(int argc, char* argv[]) 
{ 

    //get input file 
    char* infile = "card.raw"; 
    // open card file 
    FILE* inptr; 
    inptr = fopen("card.raw", "r"); 


    // error checking (copied from copy.c) 
    if (inptr == NULL) 
    { 
     printf("Could not open %s.\n", infile); 
     return 2; 
    } 

    // initialize buffer 
    BYTE buffer[512]; 

    //initialize jpg variables: 
    int increment = 0; 
    char outfilename[8]; 

    // while the end of the file is not reached, continue process & write to buffer next block of 512 bytes 
    while (fread(buffer, 512, 1, inptr) != 0) 
    { 
     // if the inpointer is not empty 
     if(inptr != NULL) 
     { 
      // If the block of 512 bytes starts with markers 
      if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3]== 0xe1 || buffer[3]== 0xe0)) 
      { 
       // increase file number by 1 
       sprintf(outfilename,"%.3d.jpg", ++increment); 

       // open new file 
       FILE* outptr; 
       outptr = fopen(outfilename, "a"); 

       // write first block of 512 bytes, then read next block 
       fwrite(buffer, 512, 1, outptr); 

       if(fread(buffer, 512, 1, inptr) == 0) 
         break; 

       // copy all information from inpointer to buffer to jpg 
       while((buffer[0] != 0xff && buffer[1] != 0xd8 && buffer[2] != 0xff && (buffer[3]!= 0xe1 || buffer[3]!= 0xe0))) 
       { 
        // if next byte is NULL break 
        if(fread(buffer, 512, 1, inptr) == 0) 
         break; 

        fread(buffer, 512, 1, inptr); 

        //copies jpg file 1 byte at a time 
        fwrite(buffer, 512, 1, outptr); 

       } 

       // close file 
       fclose(outptr); 
      } 
     } 

    } 
    return 0; 
} 
+1

歡迎來到Stack Overflow。請儘快閱讀[關於]頁面。一般來說,如果代碼運行,至少可以爭論它可能屬於[代碼評論](http://codereview.stackexchange.com/)。如果它不起作用,那麼你需要顯示不工作的代碼,也可能是一個(鏈接到)樣本破壞的圖像,它失敗了。通常,人們不太喜歡去其他網站獲取代碼。當操作代碼長度只有70多行時,你可以在這裏粘貼它。 – 2014-08-31 18:59:33

回答

4

有一個在你的問題有很多遺漏的信息,但我可以看到一些潛在的問題:

  1. 你只檢查每個512字節塊開始時的JPEG文件。除非確保這種情況,否則您應該檢查整個內存塊中的JPEG文件的啓動情況。
  2. 您只能檢查啓動了FFD8FFE1或FFD8FFE0的JPEG文件。如果JPEG中的第二個塊不是FFE1/FFE0會怎麼樣?
  3. 在你的第二個if塊下面的檢查是不正確的:

    (buffer[3] != 0xe1 || buffer[3] != 0xe0) 
    

    這始終是真實的爲buffer[3]不能同時既0xE1和取0xE0。這應該是:

    (buffer[3] != 0xe1 && buffer[3] != 0xe0) 
    
  4. 您的JPEG圖像結束檢查可能不會做你想要的東西:

    while (buffer[0] != 0xff && buffer[1] != 0xd8 && 
         buffer[2] != 0xff && buffer[3] != 0xe1 && buffer[3]!= 0xe0) 
    

    這結束JPEG當你發現這些值的任何在512字節塊的開始。例如,字節01DB0203將結束JPEG,因爲buffer[1] != 0xd8爲false,即使這不是JPEG塊標記。

  5. 我認爲查找JPEG文件的結尾會要求您搜索整個內存塊以查找表示JPEG file結束的FFD9字節標記。如果我瞭解JPEG格式,則正確的FFD9字節組合只能出現在有效的JPEG文件的末尾。
  6. 如果您仍然遇到問題,我會創建一個由多個已知的JPEG文件和其他數據組成的測試文件。然後,您可以直接比較正在輸出的內容和您應該輸出的內容,以縮小導致問題的位置/內容的範圍。
+0

0xFFE0是JFIF簽名,而0xFFE1是EXIF。這些將覆蓋99.9%以上的Jpeg文件。 – rodrigo 2014-08-31 19:06:55