-2

jpg 画像を復元する方法について質問があります (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;
}
4

1 に答える 1

4

あなたの問題には多くの情報が欠けていますが、潜在的な問題がいくつか見られます。

  1. 各 512 バイト ブロックの先頭にある JPEG ファイルのみをチェックします。これが事実であることが保証されていない限り、おそらくメモリブロック全体でJPEGファイルの開始を確認する必要があります。
  2. FFD8FFE1 または FFD8FFE0 で始まる JPEG ファイルのみをチェックします。JPEG の 2 番目のブロックが FFE1/FFE0 でない場合はどうなりますか?
  3. 2 番目のブロックの次のチェックifは正しくありません。

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

    buffer[3]同時に 0xE1 と 0xE0 の両方になることはできないため、これは常に true です。これは次のようになります。

    (buffer[3] != 0xe1 && buffer[3] != 0xe0)
    
  4. JPEG 画像の終わりをチェックしても、おそらく意図したとおりにはなりません。

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

    512 バイト ブロックの先頭にこれらの値のいずれかが見つかると、これで JPEG が終了します。たとえば、バイト 01DB0203 はbuffer[1] != 0xd8、これが JPEG ブロック マーカーではない場合でも、false であるため JPEG を終了します。

  5. JPEG ファイルの終わりを見つけるには、JPEG ファイルの終わりを示す FFD9 バイト マーカーをメモリ ブロック全体で検索する必要があると思います。JPEG 形式が正しいことを理解していれば、FFD9 バイトの組み合わせは、有効な JPEG ファイルの末尾にのみ発生します。
  6. それでも問題が発生する場合は、いくつかの既知の JPEG ファイルとその他のデータで構成されるテスト ファイルを作成します。次に、出力されているものと、出力されるべきであることがわかっているものを直接比較して、問題の原因/原因を絞り込むことができます。
于 2014-08-31T18:59:29.300 に答える