jpg неправильный, смесь нескольких изображений. Кто-нибудь может сказать мне, что не так? «ВОССТАНОВЛЕНИЕ»

Я работаю над восстановлением CS50 PSET3. У меня есть файл "card.raw", в котором jpg расположены один за другим после первого.

Целью упражнения является «найти первый jpg, сканируя каждый раз 512 байт и проверяя, является ли он началом jpg, затем добавляя следующие байты в файл до тех пор, пока не будет найдено начало следующего jpg, затем открывая другой файл и повторяя до КОНЦА ИЗ ФАЙЛ".

Изображения не создаются должным образом, и я не уверен, в чем заключается моя проблема в приведенном ниже коде.

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

int main(int argc, char *argv[])
{
    //check if program argument count is correct
    if ( argc != 2)
    {
        fprintf(stderr,"Usage: ./recover image\n");
        return(1);
    }

    char *infile = argv[1];    //Remember file name

    //open file for reading
    FILE *inptr = fopen(infile,"r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return(2);
    }

    typedef uint8_t BYTE;      //new name BYTE

    BYTE buffer[512];          // temporary  storage

    int counter = 0;           // image counter

    while (fread(buffer, 512, 1, inptr) == 1)
    {
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            char filename[8];

            start:
            sprintf(filename,"%03i.jpg", counter);
            FILE *outptr = fopen(filename,"w");
            fwrite(buffer, 512, 1,outptr);

            //check next byte
             while (fread(buffer, 512, 1, inptr) == 1)
             {
                  if (buffer[0] != 0xff && buffer[1] != 0xd8 && buffer[2] != 0xff && (buffer[3] & 0xf0) != 0xe0)
                  {
                      fwrite(buffer, 512, 1,outptr);
                      printf("%i",counter);
                  }

                  //if next file starts
                  if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
                  {
                      counter++;
                      printf("%i",counter);
                      fclose(outptr);
                      goto start;
                  }
             }
             if (counter > 1)
             {
                 fclose(outptr);
             }
        }
    }
    fclose(inptr);
}

person Rohit_    schedule 09.07.2019    source источник
comment
Возможно, это следует разместить на cs50.stackexchange.com/questions/tagged/pset3, а не здесь?   -  person Richard Chambers    schedule 09.07.2019
comment
да, я тоже разместил его там, я подумал, что будет лучше разместить его на обоих (разных) сайтах. Должен ли я удалить его?   -  person Rohit_    schedule 09.07.2019
comment
добавил дополнительную информацию и завершил программу.   -  person Rohit_    schedule 09.07.2019
comment
См. stackoverflow.com/questions/54726027/, похоже, на ту же тему и упражнение.   -  person Richard Chambers    schedule 09.07.2019
comment
я не решался добавить полный код, так как в прошлый раз, когда я это делал, веб-сайт упомянул, что я просто скопировал и вставил весь код, поэтому мне не разрешили публиковать. мне пришлось срубить код.   -  person Rohit_    schedule 09.07.2019
comment
и спасибо, я посмотрю по этой ссылке, если смогу найти похожие проблемы и понять.   -  person Rohit_    schedule 09.07.2019
comment
Код для обнаружения изменений в файле довольно неуклюж. Вы проверили это один раз, а затем вы проверяете это снова, что уже известно. На самом деле примерно в 3 раза. Я бы пересмотрел управление потоком и избавился от уродливого goto.   -  person Weather Vane    schedule 09.07.2019
comment
Я проверяю код 2 раза и оба раза использую его сразу оба раза, а потом процесс повторяется, я новичок не нашел лучшего способа. ^_^   -  person Rohit_    schedule 09.07.2019
comment
В таких кодах обычный метод заключается в обнаружении сигнатуры jpeg один раз и, если она найдена, закрытии текущего файла, генерации следующего имени файла, открытии нового файла и продолжении, закрытии его, когда нет больше данных для чтения. Не требуется goto и нет вложенного цикла. Все, что требуется, — это один цикл: прочитать каждый блок; подпись в формате jpeg? закрыть файл, открыть новый файл; блок записи.   -  person Weather Vane    schedule 09.07.2019


Ответы (1)


Можно было бы написать лучший код, но если это просто логика, то

if (buffer[0] != 0xff && buffer[1] != 0xd8 && buffer[2] != 0xff && (buffer[3] & 0xf0) != 0xe0)
                  {
                      fwrite(buffer, 512, 1,outptr);
                      printf("%i",counter);
                  }

Это неправильно, так должно быть

if (!(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0))
                  {
                      fwrite(buffer, 512, 1,outptr);
                      printf("%i",counter);
                  }

Как и в предыдущем случае, также игнорируется любая часть jpg, в которой один или несколько первых 4 байтов равны началу IMG, но не все. Спасибо всем за помощь.

person Rohit_    schedule 11.07.2019