BMP 颜色反转功能不起作用

Function for BMP color inverting doesn't work

我写了一些应该反转 BMP 图像颜色的快速代码。 我使用由 paint 创建的 40x40 维 BMP 图像进行测试。 但是该函数似乎用白色像素完全填充它。

void
negate
(char *FILE_NAME)
{
    FILE* fp = fopen(FILE_NAME, "r+b");
    uint_64 raw_data, i;

    fseek(fp, 35, SEEK_SET);
    //raw_data = fgetc(fp) + fgetc(fp)*256;
    raw_data = 4800; // calculated

    fseek(fp, 54, SEEK_SET);
    for(i = 54; i != 54 + raw_data; i++) // <=
    {
        int old = fgetc(fp);
        fseek(fp, i, SEEK_SET);
        fputc(255 - old, fp);
    }

    fclose(fp);
}

我哪里弄错了?

在循环中添加一个 fseek 修复它,虽然我不明白为什么:

for (i = 54; i != 54 + raw_data; i++) // <=
{
    fseek(fp, i, SEEK_SET);
    int old = fgetc(fp);

    fseek(fp, i, SEEK_SET);
    fputc(255 - old, fp);
}

为了找出问题,我这样做了,看看流中的位置是否正确:

for (i = 54; i != 54 + raw_data; i++) // <=
{
    long x = ftell(fp);
    printf("%d,", x);

    int old = fgetc(fp);

    fseek(fp, i, SEEK_SET);
    fputc(255 - old, fp);
}

确实如此。它输出 54,55,56,57,... 所以 fseek() 应该不是必需的!但是,如果您查看 fgetc() 的结果,"old" 值似乎总是读取 54 处的像素。我认为 @RSahu 是正确的:不要像那样对一个文件进行读写。最好将数据读入缓冲区,然后取反缓冲区,然后将其写入磁盘。或者完全写入不同的文件。

也许这与缓冲有关?

C11 规范草案对这个问题有这样的说法

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end- of-file.