cs50 的 copy.c 文件如何找到位图文件的正确部分?

how does cs50's copy.c file actually find the correct part of the bitmap file?

经过长时间的拖延,我回到了 cs50x2019 的第 3 周 - 但意识到我忘记了 whodunit 练习中的一些位图内容,所以我需要在继续调整大小之前进行研究。

我在理解 copy.c 如何实际找到 bmp 文件的相关部分以完成它的工作时遇到了一些问题。

这是他们代码的相关部分 -

    BITMAPFILEHEADER bf;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

据我了解,他们在这里创建指针并将所有输入文件存储在那里或仅存储特定部分。

// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
    if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
        bi.biBitCount != 24 || bi.biCompression != 0)

他们正在根据 bmp.h 检查结构,以确保在继续之前一切正常。

但是,他们说位图文件的哪一部分被存储在什么地方?

如果不是,那么 bf.bftype 和 bi.bftype 是等价的吗?

有必要同时拥有bf和bi吗?

我觉得我遗漏了一些非常明显的东西。

满copy.c以下

// Copies a BMP file

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

#include "bmp.h"

int main(int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 3)
    {
        printf("Usage: copy infile outfile\n");
        return 1;
    }

    // remember filenames
    char *infile = argv[1];
    char *outfile = argv[2];

    // open input file
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        printf("Could not open %s.\n", infile);
        return 2;
    }

    // open output file
    FILE *outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        printf("Could not create %s.\n", outfile);
        return 3;
    }

    // read infile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

    // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
    if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
        bi.biBitCount != 24 || bi.biCompression != 0)
    {
        fclose(outptr);
        fclose(inptr);
        printf("Unsupported file format.\n");
        return 4;
    }

    // write outfile's BITMAPFILEHEADER
    fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

    // write outfile's BITMAPINFOHEADER
    fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);

    // determine padding for scanlines
    int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        // iterate over pixels in scanline
        for (int j = 0; j < bi.biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

            // write RGB triple to outfile
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
        }

        // skip over padding, if any
        fseek(inptr, padding, SEEK_CUR);

        // then add it back (to demonstrate how)
        for (int k = 0; k < padding; k++)
        {
            fputc(0x00, outptr);
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

从 Gaga 那里偷东西:就是这么定义的。

But, how and where are they saying which part of the bitmap file is being stored?

第一个 fread 正在读取第一个 sizeof(BITMAPFILEHEADER) 字节,根据 Microsoft 的定义和 bmp.h

中的 BITMAPFILEHEADER 定义,这是 14

第二个 fread 读取接下来的 sizeof(BITMAPINFOHEADER) 个字节,根据相同的定义,这是 40 个字节。

and if they aren't, then are bf.bftype and bi.bftype equivalent?

没有bi.bftype.

is there a need for having both bf and bi?

当然可以。每个结构中存储了不同的信息。

也许研究一下规范中的这张图片如何对应 bmp.h

不要忘记按照规范中的建议访问 bmp.h 中的 Microsoft 链接。

附录:

Is the only reason the code is able to accurately pull the relevant bites because 'fread' remembers the position in the file?

没错!