CS50: я не могу открыть JPG, который создает моя программа восстановления изображений - PullRequest
0 голосов
/ 24 апреля 2020

Как я сказал в заголовке, я не могу открыть JPG, который создает моя программа восстановления изображений. Цель этой программы - сканировать infile аргумента для JPEG-файлов размером 512 байт за раз. Если блок сообщает о начале нового файла, программа должна закрыть последний файл, открыть новый файл и начать запись в него. Если данные в блоке не являются началом нового файла, программа должна продолжить запись в текущий файл. Моя программа создает 50 файлов, это количество фотографий в инфиле. Однако, когда я пытаюсь открыть их, мне говорят «Неверный или неподдерживаемый формат изображения».

Может кто-нибудь предложить какой-нибудь совет, так как я немного озадачен?

Вот мой код

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

typedef uint8_t  BYTE;

BYTE block[512];

int main(int argc, char *argv[])
{
  if (argc != 2)
    {
      printf("Usage: ./recover filename\n");
      return 1;
    }

  char *card = argv[1];
  FILE *raw_data = fopen(card, "r");

  if (raw_data == NULL)
    {
      printf("Couldn't open file.\n");
      return 1;
    }

  char file_name[8];
  BYTE buffer[512];
  int counter = 0;
  FILE *image = NULL;

  while (fread(buffer, sizeof(block), 1, raw_data) != 0)
    {
      if (counter == 0)
    {
      sprintf(file_name, "%03i.jpg", counter);
      image = fopen(file_name, "w");
      fwrite(&buffer, sizeof(block), 1, image);
      counter++;
    }

      else if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
    {
      fclose(image);
      sprintf(file_name, "%03i.jpg", counter);
      image = fopen(file_name, "w");
      counter++;
    }
      else
    {
      fwrite(&buffer, sizeof(block), 1, image);
    }
    }

  fclose(raw_data);
  fclose(image);
  return 0;

}

1 Ответ

2 голосов
/ 25 апреля 2020

Ответ на ваш вопрос находится в этом операторе if.

else if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            fclose(image);
            sprintf(file_name, "%03i.jpg", counter);
            image = fopen(file_name, "w");
            counter++;
        }

Когда в начале каждого 512-байтового блока есть подпись jpeg, этот оператор выполняется. Вы закрываете файл изображения, если он был открыт ранее. Вы создаете новый файл изображения и открываете его для записи. Но потом?? Вы не записали буфер в файл изображения, где он имеет подпись jpeg .. Бам! Ваш файл JPEG не поддерживается! Как компьютер может узнать, что это jpeg без подписи jpeg?

В то время как l oop есть другие проблемы. Даже если вы исправили основную проблему, ваш первый файл JPEG будет просто мусором .. Почему? Посмотрите на это, если утверждение ниже. Он пишет самый первый 512-байтовый блок необработанного файла без какой-либо проверки, несет ли он подпись jpeg или нет.

if (counter == 0)
{
    sprintf(file_name, "%03i.jpg", counter);
    image = fopen(file_name, "w");
    fwrite(&buffer, sizeof(block), 1, image);
    counter++;
}

Самый первый if statement в то время как l oop должен быть скорее проверьте , имеет ли 512-байтовый блок памяти подпись jpeg или нет. Псевдокод для нового дизайна поможет вам. Потому что вы, вероятно, хотите решить другие проблемы самостоятельно.

//If the buffer starts with the magic sequence found in the original code.
    //If there is already an image found, then close. (Check if counter is not equal to zero.
    //Create a new jpeg file.
    //Open that new jpeg file.
//Write buffer on new jpeg file. This one should be outside of the main if statement.

Удачи в решении других проблем. Вы довольно близки

...