C. CS50恢复作业,恢复Jpg图像

标签 c jpeg recover file-recovery cs50

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

我已经尝试解决这个练习有一段时间了,但我似乎不明白为什么它不起作用。有人可以插入我走向正确的方向吗?

这是我的代码(也可在 http://pastebin.com/U2pwJd5e 获取):

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

#include "bmp.h"


int main(int argc, char* argv[])
{

    //get input file
    char* infile = "card.raw";
    // open card file
    FILE* inptr;
    inptr = fopen("card.raw", "r");


    // error checking (copied from copy.c)
    if (inptr == NULL)
    {
        printf("Could not open %s.\n", infile);
        return 2;
    }

    // initialize buffer
    BYTE buffer[512];

    //initialize jpg variables:
    int increment = 0;
    char outfilename[8];

    // while the end of the file is not reached, continue process & write to buffer next block of 512 bytes
    while (fread(buffer, 512, 1, inptr) != 0)
    {
        // if the inpointer is not empty
        if(inptr != NULL)
        {
            // If the block of 512 bytes starts with markers
            if(buffer[0] == 0xff  && buffer[1] == 0xd8  && buffer[2] == 0xff && (buffer[3]== 0xe1 || buffer[3]== 0xe0))
            {
                // increase file number by 1
                sprintf(outfilename,"%.3d.jpg", ++increment);

                // open new file
                FILE* outptr;
                outptr = fopen(outfilename, "a");

                // write first block of 512 bytes, then read next block
                fwrite(buffer, 512, 1, outptr);

                if(fread(buffer, 512, 1, inptr) == 0)
                       break;

                // copy all information from inpointer to buffer to jpg
                while((buffer[0] != 0xff  && buffer[1] != 0xd8  && buffer[2] != 0xff && (buffer[3]!= 0xe1 || buffer[3]!= 0xe0) ))
                {
                    // if next byte is NULL break
                    if(fread(buffer, 512, 1, inptr) == 0)
                        break;

                    fread(buffer, 512, 1, inptr);

                    //copies jpg file 1 byte at a time
                    fwrite(buffer, 512, 1, outptr);

                }

                // close file
                fclose(outptr);
            }  
        }

    }
    return 0;
}

最佳答案

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

  1. 您仅在每个 512 字节 block 的开头检查 JPEG 文件。除非您能保证确实如此,否则您可能应该检查整个内存块中是否有 JPEG 文件的开头。
  2. 您仅检查以 FFD8FFE1 或 FFD8FFE0 开头的 JPEG 文件。如果 JPEG 中的第二个 block 不是 FFE1/FFE0 怎么办?
  3. 第二个 if block 中的以下检查不正确:

    (buffer[3] != 0xe1 || buffer[3] != 0xe0)
    

    这始终是正确的,因为 buffer[3] 不能同时为 0xE1 和 0xE0。这应该是:

    (buffer[3] != 0xe1 && buffer[3] != 0xe0)
    
  4. 您对 JPEG 图像结尾的检查可能没有达到您想要的效果:

    while ( buffer[0] != 0xff && buffer[1] != 0xd8 &&
            buffer[2] != 0xff && buffer[3] != 0xe1 && buffer[3]!= 0xe0 )
    

    当您在 512 字节 block 的开头找到任何这些值时,JPEG 就会结束。例如,字节 01DB0203 将结束 JPEG,因为 buffer[1] != 0xd8 为 false,即使这不是 JPEG block 标记。

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

关于C. CS50恢复作业,恢复Jpg图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25594775/

相关文章:

c - C 上的 strcmp() 中的段错误

c - 在 C 中通过具有正确填充和字节序的套接字发送结构

html - 如何制作 HTML 页面(jpeg、png 等)的屏幕截图?

ubuntu - 在 Filezilla 中恢复保存的密码

mysql - 有没有办法恢复一个多月前删除的Mysql中已删除的行

c - 我如何使用一组用户输入计算多种方法?

c++ - 使用 C++ 或 C 处理图像

iphone - 如何在 iOS 中将 UIImage 保存为渐进式 JPEG 格式?

javascript - 使用 javascript 将 bmp 转换为 jpeg

java - 恢复未保存的更改 - Eclipse