gpt4 book ai didi

c - 使用 C 从 .raw 文件恢复 JPEG 图像

转载 作者:行者123 更新时间:2023-12-05 03:56:51 26 4
gpt4 key购买 nike

我正在做 Harvard's online lecture 提供的问题集.我终于找到了从文件 (card.raw) 中恢复一组 JPEG 图像的解决方案。

似乎代码本身并没有抛出错误,但它返回的是扭曲的图像,我有点不知道为什么会发生这种情况。

[链接到图像示例] https://prnt.sc/q0tb4f

这是我的代码

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


int main(int argc, char *argv[])
{
//check usage
if (argc != 2)
{
return 1;
}
// open file
FILE* input = fopen(argv[1], "r");
// return error if file does not existS
if (!input)
{
return 1;
printf("file does not exists");
}
// create an array with 512 bytess of bytes
unsigned char bytes[512];
// create count variable
int count = 0;
// create an empty string for filename
char filename[7];
// create an empty output file
FILE* output = NULL;
// repeat until end of input
while (fread(bytes, 1, sizeof(bytes), input) != 0)
{
// read 1 block of 512 bytes at a time
fread(bytes, 1, sizeof(bytes), input);

// check if beginning of jpeg file
if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff && (bytes[3] & 0xf0) == 0xe0)
{
// if already found a jpeg, close the file
if (count > 0)
{
fclose(output);
}
// name file
sprintf(filename, "%03i.jpg", count);
// open file
output = fopen(filename, "w");
// write file
fwrite(bytes, 1, sizeof(bytes), output);
// increment count
count++;
}
if (output != NULL)
{
// keep writing if jpeg header is already found
fwrite(bytes, 1, sizeof(bytes), output);
}
}
fclose(output);
fclose(input);
}

我没有受过教育的假设无法理解为什么会发生这种情况。我只能想象这可能是由于在不正确的步骤中打开和关闭文件而发生的。

最佳答案

问题是:

while (fread(bytes, 1, sizeof(bytes), input) != 0)
{
// read 1 block of 512 bytes at a time
fread(bytes, 1, sizeof(bytes), input);

您在每个循环中调用两次 fread。结果,循环体只能看到奇数 block 。删除第二个 fread

第二个问题(如 @SteveFriedl 指出的那样)是代码用于文件名的缓冲区太小。

char filename[7];
sprintf(filename, "%03i.jpg", count);

像“123.jpg”这样的文件名至少需要 8 个字节,因为您需要为 NUL 终止符留出空间。但是,请注意"%03i" 使用至少 3 个字符。它可以使用更多,例如如果 count 达到 1000。所以我会将缓冲区声明为 char filename[32]; 以避免任何缓冲区溢出的机会。

当只需要一个时,您还有两个 fwrites:

        output = fopen(filename, "w");
// write file
fwrite(bytes, 1, sizeof(bytes), output);
// increment count
count++;
}
if (output != NULL)
{
// keep writing if jpeg header is already found
fwrite(bytes, 1, sizeof(bytes), output);
}

打开一个新文件后,代码写入第一个 block ,然后再次写入。删除第一个 fwrite 并让第二个 fwrite 处理第一个 block 。

另一个问题是代码做了一个隐含的假设,即如果 fread 不返回 0,那么它会读取一个完整的 block 。如果文件大小是 block 大小的倍数,那么该假设是可以的,但最好不要做任何假设。所以while循环中的条件应该是

while (fread(bytes, 1, sizeof(bytes), input) == sizeof(bytes))

关于c - 使用 C 从 .raw 文件恢复 JPEG 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59002783/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com