summaryrefslogtreecommitdiff
path: root/test/clip_ids.cpp
blob: 6ae889e1ff82e4bad129b0eb0bb3b04a2e5ae6ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#include <iostream>
#include "gtest/gtest.h"

#include <algorithm>

#include <llmr/util/clip_ids.hpp>
#include <llmr/util/std.hpp>

using namespace llmr;

TEST(ClipIDs, ClipMasks) {
    ASSERT_EQ(0, clipMask[0]);
    ASSERT_EQ(0x80, clipMask[1]);
    ASSERT_EQ(0xC0, clipMask[2]);
    ASSERT_EQ(0xE0, clipMask[3]);
    ASSERT_EQ(0xF0, clipMask[4]);
    ASSERT_EQ(0xF8, clipMask[5]);
    ASSERT_EQ(0xFC, clipMask[6]);
    ASSERT_EQ(0xFE, clipMask[7]);
    ASSERT_EQ(0xFF, clipMask[8]);
}


TEST(ClipIDs, ParentAndFourChildren) {
    std::array<std::unique_ptr<Tile>, 5> tiles {{
        std::make_unique<Tile>(Tile::ID { 1, 0, 0 }), // 1/0/0: 11000000 (3)
        std::make_unique<Tile>(Tile::ID { 1, 0, 1 }), // 1/0/1: 11100000 (3)
        std::make_unique<Tile>(Tile::ID { 1, 1, 0 }), // 1/1/0: 10000000 (3)
        std::make_unique<Tile>(Tile::ID { 1, 1, 1 }), // 1/1/1: 10100000 (3)
        std::make_unique<Tile>(Tile::ID { 0, 0, 0 }), // 0/0/0: 10000000 (1)
    }};

    std::list<Tile *> tile_ptrs;
    std::transform(tiles.begin(), tiles.end(), std::back_inserter(tile_ptrs), [](std::unique_ptr<Tile> &tile) { return tile.get(); });

    updateClipIDs(tile_ptrs);

    // for (const auto &it : tiles) {
    //     std::cout << std::string(it->id) << ": " << it->clip.mask << " (" << (int)it->clip.length << ")" << std::endl;
    // }

    ASSERT_EQ(std::bitset<8>("11000000"), tiles[0]->clip.mask); ASSERT_EQ(3, tiles[0]->clip.length);
    ASSERT_EQ(std::bitset<8>("11100000"), tiles[1]->clip.mask); ASSERT_EQ(3, tiles[1]->clip.length);
    ASSERT_EQ(std::bitset<8>("10000000"), tiles[2]->clip.mask); ASSERT_EQ(3, tiles[2]->clip.length);
    ASSERT_EQ(std::bitset<8>("10100000"), tiles[3]->clip.mask); ASSERT_EQ(3, tiles[3]->clip.length);
    ASSERT_EQ(std::bitset<8>("10000000"), tiles[4]->clip.mask); ASSERT_EQ(1, tiles[4]->clip.length);
}

TEST(ClipIDs, ParentAndFourChildrenNegative) {
    std::array<std::unique_ptr<Tile>, 5> tiles {{
        std::make_unique<Tile>(Tile::ID { 1, -2, 0 }), // 1/0/0: 11000000 (3)
        std::make_unique<Tile>(Tile::ID { 1, -2, 1 }), // 1/0/1: 11100000 (3)
        std::make_unique<Tile>(Tile::ID { 1, -1, 0 }), // 1/1/0: 10000000 (3)
        std::make_unique<Tile>(Tile::ID { 1, -1, 1 }), // 1/1/1: 10100000 (3)
        std::make_unique<Tile>(Tile::ID { 0, -1, 0 }), // 0/0/0: 10000000 (1)
    }};

    std::list<Tile *> tile_ptrs;
    std::transform(tiles.begin(), tiles.end(), std::back_inserter(tile_ptrs), [](std::unique_ptr<Tile> &tile) { return tile.get(); });

    updateClipIDs(tile_ptrs);

    // for (const auto &it : tiles) {
    //     std::cout << std::string(it->id) << ": " << it->clip.mask << " (" << (int)it->clip.length << ")" << std::endl;
    // }

    ASSERT_EQ(std::bitset<8>("11000000"), tiles[0]->clip.mask); ASSERT_EQ(3, tiles[0]->clip.length);
    ASSERT_EQ(std::bitset<8>("11100000"), tiles[1]->clip.mask); ASSERT_EQ(3, tiles[1]->clip.length);
    ASSERT_EQ(std::bitset<8>("10000000"), tiles[2]->clip.mask); ASSERT_EQ(3, tiles[2]->clip.length);
    ASSERT_EQ(std::bitset<8>("10100000"), tiles[3]->clip.mask); ASSERT_EQ(3, tiles[3]->clip.length);
    ASSERT_EQ(std::bitset<8>("10000000"), tiles[4]->clip.mask); ASSERT_EQ(1, tiles[4]->clip.length);
}

TEST(ClipIDs, NegativeParentAndMissingLevel) {
    std::array<std::unique_ptr<Tile>, 5> tiles {{
        std::make_unique<Tile>(Tile::ID { 1, -1, 0 }), // 1/-1/0: 10000000 (1)
        std::make_unique<Tile>(Tile::ID { 2, -1, 0 }), // 2/-1/0: 10000000 (3)
        std::make_unique<Tile>(Tile::ID { 2, -2, 1 }), // 2/-2/1: 11100000 (3)
        std::make_unique<Tile>(Tile::ID { 2, -1, 1 }), // 2/-1/1: 10100000 (3)
        std::make_unique<Tile>(Tile::ID { 2, -2, 0 }), // 2/-2/0: 11000000 (3)
    }};

    std::list<Tile *> tile_ptrs;
    std::transform(tiles.begin(), tiles.end(), std::back_inserter(tile_ptrs), [](std::unique_ptr<Tile> &tile) { return tile.get(); });

    updateClipIDs(tile_ptrs);

    // for (const auto &it : tiles) {
    //     std::cout << std::string(it->id) << ": " << it->clip.mask << " (" << (int)it->clip.length << ")" << std::endl;
    // }

    ASSERT_EQ(std::bitset<8>("10000000"), tiles[0]->clip.mask); ASSERT_EQ(1, tiles[0]->clip.length);
    ASSERT_EQ(std::bitset<8>("10000000"), tiles[1]->clip.mask); ASSERT_EQ(3, tiles[1]->clip.length);
    ASSERT_EQ(std::bitset<8>("11100000"), tiles[2]->clip.mask); ASSERT_EQ(3, tiles[2]->clip.length);
    ASSERT_EQ(std::bitset<8>("10100000"), tiles[3]->clip.mask); ASSERT_EQ(3, tiles[3]->clip.length);
    ASSERT_EQ(std::bitset<8>("11000000"), tiles[4]->clip.mask); ASSERT_EQ(3, tiles[4]->clip.length);
}


TEST(ClipIDs, SevenOnSameLevel) {
    std::array<std::unique_ptr<Tile>, 7> tiles {{
        std::make_unique<Tile>(Tile::ID { 2, 0, 0 }), // 2/0/0: 11000000 (3)
        std::make_unique<Tile>(Tile::ID { 2, 0, 1 }), // 2/0/1: 11100000 (3)
        std::make_unique<Tile>(Tile::ID { 2, 0, 2 }), // 2/0/2: 10000000 (3)
        std::make_unique<Tile>(Tile::ID { 2, 1, 0 }), // 2/1/0: 10100000 (3)
        std::make_unique<Tile>(Tile::ID { 2, 1, 1 }), // 2/1/1: 01000000 (3)
        std::make_unique<Tile>(Tile::ID { 2, 1, 2 }), // 2/1/2: 01100000 (3)
        std::make_unique<Tile>(Tile::ID { 2, 2, 0 }), // 2/2/0: 00100000 (3)
    }};

    std::list<Tile *> tile_ptrs;
    std::transform(tiles.begin(), tiles.end(), std::back_inserter(tile_ptrs), [](std::unique_ptr<Tile> &tile) { return tile.get(); });

    updateClipIDs(tile_ptrs);

    // for (const auto &it : tiles) {
    //     std::cout << std::string(it->id) << ": " << it->clip.mask << " (" << (int)it->clip.length << ")" << std::endl;
    // }

    ASSERT_EQ(std::bitset<8>("11000000"), tiles[0]->clip.mask); ASSERT_EQ(3, tiles[0]->clip.length);
    ASSERT_EQ(std::bitset<8>("11100000"), tiles[1]->clip.mask); ASSERT_EQ(3, tiles[1]->clip.length);
    ASSERT_EQ(std::bitset<8>("10000000"), tiles[2]->clip.mask); ASSERT_EQ(3, tiles[2]->clip.length);
    ASSERT_EQ(std::bitset<8>("10100000"), tiles[3]->clip.mask); ASSERT_EQ(3, tiles[3]->clip.length);
    ASSERT_EQ(std::bitset<8>("01000000"), tiles[4]->clip.mask); ASSERT_EQ(3, tiles[4]->clip.length);
    ASSERT_EQ(std::bitset<8>("01100000"), tiles[5]->clip.mask); ASSERT_EQ(3, tiles[5]->clip.length);
    ASSERT_EQ(std::bitset<8>("00100000"), tiles[6]->clip.mask); ASSERT_EQ(3, tiles[6]->clip.length);
}

TEST(ClipIDs, MultipleLevels) {
    std::array<std::unique_ptr<Tile>, 12> tiles {{
        std::make_unique<Tile>(Tile::ID { 2, 0, 0 }),           // 2/0/0: 10000000 (1)
            std::make_unique<Tile>(Tile::ID { 3, 0, 0 }),       //     3/0/0: 10000000 (3)
            std::make_unique<Tile>(Tile::ID { 3, 0, 1 }),       //     3/0/1: 11100000 (3)
                std::make_unique<Tile>(Tile::ID { 4, 0, 2 }),   //         4/0/2: 11110000 (5)
                std::make_unique<Tile>(Tile::ID { 4, 1, 2 }),   //         4/0/3: 11111000 (5)
                std::make_unique<Tile>(Tile::ID { 4, 0, 3 }),   //         4/1/2: 11100000 (5)
                std::make_unique<Tile>(Tile::ID { 4, 1, 3 }),   //         4/1/3: 11101000 (5)
            std::make_unique<Tile>(Tile::ID { 3, 1, 0 }),       //     3/1/0: 10100000 (3)
            std::make_unique<Tile>(Tile::ID { 3, 1, 1 }),       //     3/1/1: 11000000 (3)
        std::make_unique<Tile>(Tile::ID { 2, 1, 0 }),           // 2/1/0: 01000000 (2)
            std::make_unique<Tile>(Tile::ID { 3, 2, 0 }),       //     3/2/0: 01010000 (4)
            std::make_unique<Tile>(Tile::ID { 3, 2, 1 }),       //     3/2/1: 01100000 (3)
    }};

    // Use a random order to verify that the result of this algorithm is independent of the
    std::random_shuffle(tiles.begin(), tiles.end());

    std::list<Tile *> tile_ptrs;
    std::transform(tiles.begin(), tiles.end(), std::back_inserter(tile_ptrs), [](std::unique_ptr<Tile> &tile) { return tile.get(); });

    updateClipIDs(tile_ptrs);

    // Sort them by tile ID so that we know what order we have to test in.
    std::sort(tiles.begin(), tiles.end(), [](const std::unique_ptr<Tile> &a, const std::unique_ptr<Tile> &b) {
        return a->id < b->id;
    });

    // for (const auto &it : tiles) {
    //     std::cout << std::string(it->id) << ": " << it->clip.mask << " (" << (int)it->clip.length << ")" << std::endl;
    // }

    ASSERT_EQ(std::string("2/0/0"), std::string(tiles[0]->id));
    ASSERT_EQ(std::bitset<8>("10000000"), tiles[0]->clip.mask);
    ASSERT_EQ(1, tiles[0]->clip.length);

    ASSERT_EQ(std::string("2/1/0"), std::string(tiles[1]->id));
    ASSERT_EQ(std::bitset<8>("01000000"), tiles[1]->clip.mask);
    ASSERT_EQ(2, tiles[1]->clip.length);

    ASSERT_EQ(std::string("3/0/0"), std::string(tiles[2]->id));
    ASSERT_EQ(std::bitset<8>("10000000"), tiles[2]->clip.mask);
    ASSERT_EQ(3, tiles[2]->clip.length);

    ASSERT_EQ(std::string("3/0/1"), std::string(tiles[3]->id));
    ASSERT_EQ(std::bitset<8>("11100000"), tiles[3]->clip.mask);
    ASSERT_EQ(3, tiles[3]->clip.length);

    ASSERT_EQ(std::string("3/1/0"), std::string(tiles[4]->id));
    ASSERT_EQ(std::bitset<8>("10100000"), tiles[4]->clip.mask);
    ASSERT_EQ(3, tiles[4]->clip.length);

    ASSERT_EQ(std::string("3/1/1"), std::string(tiles[5]->id));
    ASSERT_EQ(std::bitset<8>("11000000"), tiles[5]->clip.mask);
    ASSERT_EQ(3, tiles[5]->clip.length);

    ASSERT_EQ(std::string("3/2/0"), std::string(tiles[6]->id));
    ASSERT_EQ(std::bitset<8>("01010000"), tiles[6]->clip.mask);
    ASSERT_EQ(4, tiles[6]->clip.length);

    ASSERT_EQ(std::string("3/2/1"), std::string(tiles[7]->id));
    ASSERT_EQ(std::bitset<8>("01100000"), tiles[7]->clip.mask);
    ASSERT_EQ(3, tiles[7]->clip.length);

    ASSERT_EQ(std::string("4/0/2"), std::string(tiles[8]->id));
    ASSERT_EQ(std::bitset<8>("11110000"), tiles[8]->clip.mask);
    ASSERT_EQ(5, tiles[8]->clip.length);

    ASSERT_EQ(std::string("4/0/3"), std::string(tiles[9]->id));
    ASSERT_EQ(std::bitset<8>("11111000"), tiles[9]->clip.mask);
    ASSERT_EQ(5, tiles[9]->clip.length);

    ASSERT_EQ(std::string("4/1/2"), std::string(tiles[10]->id));
    ASSERT_EQ(std::bitset<8>("11100000"), tiles[10]->clip.mask);
    ASSERT_EQ(5, tiles[10]->clip.length);

    ASSERT_EQ(std::string("4/1/3"), std::string(tiles[11]->id));
    ASSERT_EQ(std::bitset<8>("11101000"), tiles[11]->clip.mask);
    ASSERT_EQ(5, tiles[11]->clip.length);
}


TEST(ClipIDs, Bug206) {
    std::array<std::unique_ptr<Tile>, 11> tiles {{
        std::make_unique<Tile>(Tile::ID { 10, 162, 395 }),      // 10/162/395: 10000000 (3)
        std::make_unique<Tile>(Tile::ID { 10, 162, 396 }),      // 10/162/396: 10100000 (3)
        std::make_unique<Tile>(Tile::ID { 10, 163, 395 }),      // 10/163/395: 11000000 (2)
            std::make_unique<Tile>(Tile::ID { 11, 326, 791 }),  //     11/326/791: 11100000 (4)
            std::make_unique<Tile>(Tile::ID { 12, 654, 1582 }), //     12/654/1582: 11001000 (5)
            std::make_unique<Tile>(Tile::ID { 12, 654, 1583 }), //     12/654/1583: 11010000 (4)
            std::make_unique<Tile>(Tile::ID { 12, 655, 1582 }), //     12/655/1582: 11110000 (5)
            std::make_unique<Tile>(Tile::ID { 12, 655, 1583 }), //     12/655/1583: 11111000 (5)
        std::make_unique<Tile>(Tile::ID { 10, 163, 396 }),      // 10/163/396: 01000000 (3)
        std::make_unique<Tile>(Tile::ID { 10, 164, 395 }),      // 10/164/395: 01100000 (3)
        std::make_unique<Tile>(Tile::ID { 10, 164, 396 }),      // 10/164/396: 00100000 (3)
    }};

    std::list<Tile *> tile_ptrs;
    std::transform(tiles.begin(), tiles.end(), std::back_inserter(tile_ptrs), [](std::unique_ptr<Tile> &tile) { return tile.get(); });

    updateClipIDs(tile_ptrs);

    // for (const auto &it : tiles) {
    //     std::cout << std::string(it->id) << ": " << it->clip.mask << " (" << (int)it->clip.length << ")" << std::endl;
    // }

    ASSERT_EQ(std::string("10/162/395"), std::string(tiles[0]->id));
    ASSERT_EQ(std::bitset<8>("10000000"), tiles[0]->clip.mask);
    ASSERT_EQ(3, tiles[0]->clip.length);

    ASSERT_EQ(std::string("10/162/396"), std::string(tiles[1]->id));
    ASSERT_EQ(std::bitset<8>("10100000"), tiles[1]->clip.mask);
    ASSERT_EQ(3, tiles[1]->clip.length);

    ASSERT_EQ(std::string("10/163/395"), std::string(tiles[2]->id));
    ASSERT_EQ(std::bitset<8>("11000000"), tiles[2]->clip.mask);
    ASSERT_EQ(2, tiles[2]->clip.length);

    ASSERT_EQ(std::string("11/326/791"), std::string(tiles[3]->id));
    ASSERT_EQ(std::bitset<8>("11100000"), tiles[3]->clip.mask);
    ASSERT_EQ(4, tiles[3]->clip.length);

    ASSERT_EQ(std::string("12/654/1582"), std::string(tiles[4]->id));
    ASSERT_EQ(std::bitset<8>("11001000"), tiles[4]->clip.mask);
    ASSERT_EQ(5, tiles[4]->clip.length);

    ASSERT_EQ(std::string("12/654/1583"), std::string(tiles[5]->id));
    ASSERT_EQ(std::bitset<8>("11010000"), tiles[5]->clip.mask);
    ASSERT_EQ(4, tiles[5]->clip.length);

    ASSERT_EQ(std::string("12/655/1582"), std::string(tiles[6]->id));
    ASSERT_EQ(std::bitset<8>("11110000"), tiles[6]->clip.mask);
    ASSERT_EQ(5, tiles[6]->clip.length);

    ASSERT_EQ(std::string("12/655/1583"), std::string(tiles[7]->id));
    ASSERT_EQ(std::bitset<8>("11111000"), tiles[7]->clip.mask);
    ASSERT_EQ(5, tiles[7]->clip.length);

    ASSERT_EQ(std::string("10/163/396"), std::string(tiles[8]->id));
    ASSERT_EQ(std::bitset<8>("01000000"), tiles[8]->clip.mask);
    ASSERT_EQ(3, tiles[8]->clip.length);

    ASSERT_EQ(std::string("10/164/395"), std::string(tiles[9]->id));
    ASSERT_EQ(std::bitset<8>("01100000"), tiles[9]->clip.mask);
    ASSERT_EQ(3, tiles[9]->clip.length);

    ASSERT_EQ(std::string("10/164/396"), std::string(tiles[10]->id));
    ASSERT_EQ(std::bitset<8>("00100000"), tiles[10]->clip.mask);
    ASSERT_EQ(3, tiles[10]->clip.length);

}

TEST(ClipIDs, DuplicateIDs) {

    std::forward_list<Tile::ID> tiles {{
        Tile::ID { 2, 0, 0 },
        Tile::ID { 2, 0, 1 },
        Tile::ID { 2, 0, 0 },
        Tile::ID { 2, 0, 1 },
        Tile::ID { 2, 0, 1 },
    }};

    std::map<Tile::ID, ClipID> mapping = computeClipIDs(tiles);

    ASSERT_EQ(2ull, mapping.size());

    // for (const auto &it : mapping) {
    //     std::cout << std::string(it.first) << "(" << it.first << ")" << ": " << it.second.mask << " (" << (int)it.second.length << ")" << std::endl;
    // }

    ASSERT_EQ(std::bitset<8>("01000000"), mapping[Tile::ID(2, 0, 0)].mask);
    ASSERT_EQ(2, mapping[Tile::ID(2, 0, 0)].length);

    ASSERT_EQ(std::bitset<8>("10000000"), mapping[Tile::ID(2, 0, 1)].mask);
    ASSERT_EQ(1, mapping[Tile::ID(2, 0, 1)].length);
}