C.CS50恢复分配,恢复Jpg图像

C.CS50恢复分配,恢复Jpg图像,c,jpeg,recover,file-recovery,cs50,C,Jpeg,Recover,File Recovery,Cs50,我有一个关于如何恢复jpg图像的问题(这是CS50的任务)。 我的代码大部分都能工作(我相信),但是当我打开我找到的jpg时,我只得到一堆缩略图 我已经尝试解决这个问题很长一段时间了,但我似乎不明白为什么它不起作用。谁能帮我往正确的方向推一下吗 这是我的代码(也可从以下网址获得): #包括 #包括 #包括“bmp.h” int main(int argc,char*argv[]) { //获取输入文件 char*infle=“card.raw”; //打开卡片文件 文件*inptr; inptr

我有一个关于如何恢复jpg图像的问题(这是CS50的任务)。 我的代码大部分都能工作(我相信),但是当我打开我找到的jpg时,我只得到一堆缩略图

我已经尝试解决这个问题很长一段时间了,但我似乎不明白为什么它不起作用。谁能帮我往正确的方向推一下吗

这是我的代码(也可从以下网址获得):

#包括
#包括
#包括“bmp.h”
int main(int argc,char*argv[])
{
//获取输入文件
char*infle=“card.raw”;
//打开卡片文件
文件*inptr;
inptr=fopen(“原始卡片”,“r”);
//检查错误(从copy.c复制)
如果(inptr==NULL)
{
printf(“无法打开%s。\n”,填充);
返回2;
}
//初始化缓冲区
字节缓冲区[512];
//初始化jpg变量:
整数增量=0;
字符输出文件名[8];
//未到达文件结尾时,继续处理并写入下一个512字节的缓冲区块
while(fread(缓冲区,512,1,inptr)!=0)
{
//如果输入点不是空的
如果(inptr!=NULL)
{
//如果512字节的块以标记开始
如果(缓冲区[0]==0xff&&buffer[1]==0xd8&&buffer[2]==0xff&&buffer[3]==0xe1 | |缓冲区[3]==0xe0))
{
//将文件号增加1
sprintf(outfilename,“%.3d.jpg”,++增量);
//打开新文件
文件*outptr;
outptr=fopen(outfilename,“a”);
//写入512字节的第一个块,然后读取下一个块
fwrite(缓冲区,512,1,outptr);
if(fread(缓冲器,512,1,inptr)==0)
打破
//将所有信息从输入点复制到缓冲区到jpg
而((缓冲区[0]!=0xff和缓冲区[1]!=0xd8和缓冲区[2]!=0xff和(缓冲区[3]!=0xe1 | |缓冲区[3]!=0xe0)))
{
//如果下一个字节为空,则中断
if(fread(缓冲器,512,1,inptr)==0)
打破
fread(缓冲器,512,1,inptr);
//每次复制一个字节的jpg文件
fwrite(缓冲区,512,1,outptr);
}
//关闭文件
fclose(outptr);
}  
}
}
返回0;
}

您的问题中有很多信息缺失,但我可以看到一些潜在的问题:

  • 仅在每个512字节块的开头检查JPEG文件。除非保证是这种情况,否则您可能应该在整个内存块中检查JPEG文件的开始
  • 仅检查以FFD8FFE1或FFD8FFE0开头的JPEG文件。如果JPEG中的第二个块不是FFE1/FFE0怎么办
  • 如果第二个
    块不正确,请执行以下检查:

    (buffer[3] != 0xe1 || buffer[3] != 0xe0)
    
    这总是正确的,因为
    缓冲区[3]
    不能同时为0xE1和0xE0。这应该是:

    (buffer[3] != 0xe1 && buffer[3] != 0xe0)
    
  • 检查JPEG图像的结尾可能无法满足您的要求:

    while ( buffer[0] != 0xff && buffer[1] != 0xd8 &&
            buffer[2] != 0xff && buffer[3] != 0xe1 && buffer[3]!= 0xe0 )
    
    当您在512字节块的开头找到这些值时,这将结束JPEG。例如,字节01DB0203将结束JPEG,因为
    buffer[1]!=0xd8
    为false,即使这不是JPEG块标记

  • 我认为查找JPEG文件的结尾需要在整个内存块中搜索FFD9字节标记,它表示JPEG文件的结尾。如果我理解JPEG格式正确,FFD9字节组合只能出现在有效JPEG文件的末尾
  • 如果您仍然遇到问题,我将创建一个由几个已知JPEG文件和其他数据组成的测试文件。然后,您可以直接比较正在输出的内容和您知道应该输出的内容,以缩小导致问题的位置/原因

  • 欢迎来到堆栈溢出。请尽快阅读这一页。一般来说,如果代码运行,它可能属于上一个,这至少是有争议的。如果它不起作用,那么您需要显示不起作用的代码,可能还需要显示一个(链接到一个)失败的示例损坏图像。一般来说,人们不太喜欢到另一个站点获取代码。当操作代码只有70多行长时,您可能可以将其粘贴到此处。
    0xFFE0
    是JFIF签名,而
    0xFFE1
    是EXIF。这些将覆盖超过99.9%的Jpeg文件。
    while ( buffer[0] != 0xff && buffer[1] != 0xd8 &&
            buffer[2] != 0xff && buffer[3] != 0xe1 && buffer[3]!= 0xe0 )