CS50:我无法打开我的图像恢复程序创建的 JPG
CS50: I can't open the JPG's my image recovery program creates
正如我在标题中所说,我无法打开我的图像恢复程序创建的 JPG。该程序的目的是一次扫描 512 字节块的 JPEG 文件参数。如果块发出新文件开始的信号,程序应该关闭最后一个输出文件,打开一个新的输出文件并开始写入。如果块中的数据不是新文件的开始,程序应该继续写入当前输出文件。我的程序创建了 50 个文件,这是 infile 中的照片数量。但是,当我尝试打开它们时,我被告知 "Invalid or Unsupported Image Format"。
有谁能给我一些建议,我有点难过?
这是我的代码
#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;
}
你的问题的答案在这个 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.
祝其他问题顺利解决。你很接近。
正如我在标题中所说,我无法打开我的图像恢复程序创建的 JPG。该程序的目的是一次扫描 512 字节块的 JPEG 文件参数。如果块发出新文件开始的信号,程序应该关闭最后一个输出文件,打开一个新的输出文件并开始写入。如果块中的数据不是新文件的开始,程序应该继续写入当前输出文件。我的程序创建了 50 个文件,这是 infile 中的照片数量。但是,当我尝试打开它们时,我被告知 "Invalid or Unsupported Image Format"。
有谁能给我一些建议,我有点难过?
这是我的代码
#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;
}
你的问题的答案在这个 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.
祝其他问题顺利解决。你很接近。