首页 > 解决方案 > CS50:我无法打开我的图像恢复程序创建的 JPG

问题描述

正如我在标题中所说,我无法打开我的图像恢复程序创建的 JPG。该程序的目的是一次扫描 JPEG 的参数 infile 一个 512 字节的块。如果块发出新文件开始的信号,则程序应关闭最后一个输出文件,打开一个新输出文件并开始写入。如果块中的数据不是新文件的开头,则程序应继续写入当前输出文件。我的程序创建了 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;

}

标签: cimage-processingcs50

解决方案


你的问题的答案在这个 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 签名的图像文件上写入缓冲区.. Bam!不支持您的 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.

祝你好运解决其他问题。你很接近。


推荐阅读