C++ rle bmp 压缩跳过最后字节

C++ rle bmp compression skips last bytes

我正在为 bmp 文件编写 rle 压缩。 (它是更大项目的一部分)编码功能需要一个仅包含像素的文件(没有 headers)。一切都很好,除了它不压缩最后几个字节(我猜这取决于文件大小)。解压缩也很好用。 在此先感谢您的帮助!

代码如下:

 #include <string>
#include <fstream>
#include <iostream>

using namespace std;

typedef struct SPixel {
    uint8_t red;    
    uint8_t green;
    uint8_t blue;
}PIXEL;

bool compare(SPixel pixel1, SPixel pixel2) {
    if (pixel1.red == pixel2.red && pixel1.green == pixel2.green && pixel1.blue == pixel2.blue)
        return true;
    else return false;
}

void encode(string &input, string &output){
    unsigned short repetition = 1;
    PIXEL current;
    PIXEL next;

    fstream file;
    fstream compressed;
    file.open(input, ios::in | ios::binary);
    if (!file.is_open()) {
        cout << "cannot open file to encode." << endl;
        getchar();
        exit(1);
    }

    compressed.open(output, ios::out | ios::trunc | ios::binary);
    if (!compressed.is_open()) {
        cout << "cannot open file to save encoded file." << endl;
        getchar();
        exit(1);
    }

    file.read((char*)&current, sizeof(PIXEL));
    file.read((char*)&next, sizeof(PIXEL));

    while (!file.eof())
        if (!compare(current, next)) {
            compressed.write((char*)&repetition, sizeof(repetition));
            compressed.write((char*)&current, sizeof(PIXEL));
            repetition = 0;
        }
        repetition++;
        current = next;
        file.read((char*)&next, sizeof(PIXEL));
    }

    file.close();
    compressed.close();
}

void decode(string &input, string &output) {
    fstream file;
    fstream ready;
    PIXEL current;
    unsigned short repetition = 0;

    file.open(input, ios::in | ios::binary);
    if (!file.is_open()) {
        cout << "cannot open file to decode." << endl;
        getchar();
        exit(1);
    }
    ready.open(output, ios::trunc | ios::out | ios::binary);
    if (!ready.is_open()) {
        cout << "cannot open file to save decoded file." << endl;
        getchar();
        exit(1);
    }

    while (!file.eof()){
        file.read((char*)&repetition, sizeof(repetition));
        file.read((char*)&current, sizeof(PIXEL));
        for (int j = 0; j < repetition; j++)
            ready.write((char*)&current, sizeof(PIXEL));
    }

    file.close();
    ready.close();
}

正如Some programmer dude正确提到的,您需要进行以下更正。

encode 函数中插入以下代码

while (!file.eof()) {
    ...
}

if (1 < repetition) {
    compressed.write((char*)&repetition, sizeof(repetition));
    compressed.write((char*)&current, sizeof(PIXEL));
}

file.close();
...