c - 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;
}
解决方案
你的问题的答案在这个 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.
祝你好运解决其他问题。你很接近。
推荐阅读
- php - 我有一个来自 wordpress 的错误,超过了最大时间
- python - 将 TensorFlow 张量传递给层,但不作为参数......这种做法叫什么?
- mysql - 如何将 SQL 语句转换为 Power BI DAX?
- django-rest-framework - 发送密码后从休息框架需要密码
- ios - 将 Safari 扩展从 intune 推送到 iOS
- php - 为什么 php 重定向我而不是显示警报?
- sql - 根据另一列中的共同值计算同一列中的对
- mongodb - 如何设置从多个 GCP 项目到同一个 MongoDB 集群的网络对等连接
- c# - 如何使用 cefsharp 单击按钮?
- sql - 合并 2 个 PostgreSQL 表