Поврежденные изображения jpeg возникают после восстановления из файла

Я недавно пытаюсь решить проблему с cs50 pset4 recovery. Речь идет о восстановлении изображений jpeg из необработанного файла. Проблема в том, что я могу получить изображение, но мои изображения возвращаются поврежденными. Другими словами, я хочу записать 512 байтов в каждый JPEG, но мои результирующие файлы JPEG имеют размер всего 1 байт. пожалуйста, помогите мне проверить мои коды и оптимизировать.

может извлекать изображения и просматривать
, но не исправлять содержимое и поврежденные
ожидает 512 байт каждый, но только 1 байт

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

#define MAX_SIZE  512
int main(int argc, char *argv[])

{
    typedef uint8_t BYTE;
    BYTE bufferRead[MAX_SIZE];
    char name[8];

     // Check usage
    if (argc != 2)
    {
        printf("Usage: ./recover image");
        return 1;
    }

    // Open file
    FILE *file = fopen(argv[1], "r");
    if (!file)
    {
        return 1;
    }
    FILE* img=NULL;

    int i=0;
    while(fread(bufferRead,512, 1, file))
    {    

        // Check first four bytes
        if (bufferRead[0] == 0xff && bufferRead[1] == 0xd8 && bufferRead[2] == 0xff && ((bufferRead[3]&0xf0) == 0xe0))
        {
            sprintf(name, "%03i.jpg",i);
            img=fopen(name,"w");
            
            if(img == NULL)
            {
               return 1;
            }
            
            fwrite(bufferRead,512,1, img);
            //close the file
            fclose(img);
            i++;
        }
    }
    // Close file
    fclose(file);
}

person Aung Kaung Htet    schedule 22.12.2020    source источник
comment
fwrite находится в предложении if, что означает, что он будет записывать только первый блок изображения jpeg, с которого начинается подпись, но не остальные. Вы должны переместить fwrite за пределы предложения if.   -  person Enis Arik    schedule 28.12.2020
comment
спасибо за помощь, но это оставляет мне ошибку сегментации   -  person Aung Kaung Htet    schedule 28.12.2020
comment
Вероятно, вы пытались получить доступ к указателю, который ни на что не указывает. Это запрещено и приведет к ошибке сегментации. Я опубликовал решение, пожалуйста, ознакомьтесь с ним.   -  person Enis Arik    schedule 29.12.2020


Ответы (1)


Одно изображение говорит тысячу слов. Я считаю, что визуализация того, как изображения jpeg хранятся в памяти, очень поможет.

введите описание изображения здесь

На карте памяти файлы jpeg хранятся вместе друг за другом. Как только вы найдете подпись jpeg, вы продолжаете записывать блоки памяти в файлы изображений. Но вы должны всегда проверять, найдена ли другая подпись jpeg. Затем вы должны закрыть изображение и создать еще одно. Я изменил ваш код для правильной логики, пожалуйста, проверьте комментарии о том, что они делают.

while(fread(bufferRead,512, 1, file))
{

    // Check first four bytes
    if (bufferRead[0] == 0xff && bufferRead[1] == 0xd8 && bufferRead[2] == 0xff && ((bufferRead[3]&0xf0) == 0xe0))
    {

        // If there is already an image found, then close.
        if (i != 0)
        {
            fclose(img);
        }

        // create a new jpg file.
        sprintf(name, "%03i.jpg",i++);
        // open the new jpg file.
        img=fopen(name,"w");
    }

    if(img != NULL)
    {
        // Write the data to a new jpeg file.
        fwrite(bufferRead,512,1, img);
    }

}
// Close img.
fclose(img);
// Close file.
fclose(file);
return(0);
}
person Enis Arik    schedule 29.12.2020
comment
Большое спасибо, это мне очень помогает. Теперь меня приняли чеком 50. Спасибо. - person Aung Kaung Htet; 30.12.2020