以下の手順になるかと思います。
- pgm フォーマット を解析する。
- データを run length 方式で圧縮する。
- 圧縮したデータを解凍する。
サンプルとして、こちらの pgm ファイル を使用しました。
cpp
1#include <fstream>
2#include <iostream>
3#include <iterator>
4#include <string>
5#include <vector>
6
7/**
8 @brief 圧縮する。
9 @param src 圧縮前のデータ
10 @param dst 圧縮後のデータ
11 */
12void compress(const std::vector<int> &src, std::vector<int> &dst)
13{
14 for (int i = 0; i < src.size(); ++i) {
15 int count = 1;
16 // 同じ値が続く限り進める。
17 while (i < src.size() - 1 && src[i] == src[i + 1]) {
18 ++count;
19 ++i;
20 }
21
22 dst.push_back(src[i]); // 値
23 dst.push_back(count); // 連続する個数
24 }
25}
26
27/**
28 @brief 解凍する。
29 @param src 解凍前のデータ
30 @param dst 解凍後のデータ
31 */
32void uncompress(const std::vector<int> &src, std::vector<int> &dst)
33{
34 for (int i = 0; i < src.size(); i += 2) {
35 int val = src[i];
36 int count = src[i + 1];
37
38 for (int j = 0; j < count; ++j)
39 dst.push_back(val);
40 }
41}
42
43int main()
44{
45 std::string imgPath = R"(sample.pgm)";
46
47 // ファイルを解析する。
48 // 参考: https://people.sc.fsu.edu/~jburkardt/data/pgma/pgma.html
49 std::string version;
50 int width, height, maxValue;
51
52 std::ifstream ifs(imgPath);
53 // ヘッダー
54 ifs >> version >> width >> height >> maxValue;
55 // 画素値
56 std::vector<int> data(
57 std::istream_iterator<int>{ifs}, std::istream_iterator<int>());
58
59 std::cout << "version: " << version << std::endl;
60 std::cout << "size: " << width << "x" << height << std::endl;
61 std::cout << "max value: " << maxValue << std::endl;
62
63 // run length 圧縮
64 std::vector<int> compressed;
65 compress(data, compressed);
66 std::cout << "row size: " << data.size() << std::endl;
67 std::cout << "compressed size: " << compressed.size() << std::endl;
68
69 // 解凍する。
70 std::vector<int> uncompressed;
71 uncompress(compressed, uncompressed);
72
73 // 圧縮前とデータが一致するか
74 bool allEqual = true;
75 for (int i = 0; i < data.size(); ++i)
76 allEqual &= data[i] == uncompressed[i];
77 std::cout << "all equal: " << allEqual << std::endl;
78
79 ifs.close();
80}
81
出力結果
version: P2
size: 600x600
max value: 255
row size: 360000
compressed size: 51782
all equal: 1