CS50:我无法打开JPG,这是我的图像恢复程序创建的

时间:2020-04-24 15:38:25

标签: c image-processing cs50

正如标题中所述,我无法打开我的图像恢复程序创建的JPG。该程序的目的是一次扫描一个512字节块的参数infile中的JPEG。如果该块指示新文件已开始,则程序应关闭最后一个输出文件,打开一个新的输出文件并开始对其进行写入。如果块中的数据不是新文件的开始,则程序应继续写入当前输出文件。我的程序创建了50个文件,这是infile中的照片数量。但是,当我尝试打开它们时,系统会提示我“图像格式无效或不受支持”。

有人会为我有些困惑而提供任何建议吗?

这是我的代码

#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 个答案:

答案 0 :(得分:2)

问题的答案在else 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?

while循环中还有其他问题。即使您修复了主要问题,您的第一个jpeg文件也将只是垃圾。为什么?请在下面查看此if语句。它正在写入原始文件的第一个512字节块,而没有检查是否带有jpeg签名。

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

while循环中的第一个if statement应该是检查,如果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.

祝您解决其他问题好运。你很亲密