-
Notifications
You must be signed in to change notification settings - Fork 0
/
Block.hpp
119 lines (92 loc) · 3.92 KB
/
Block.hpp
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
#ifndef BLOCK_HPP
#define BLOCK_HPP
#include "BitStream.hpp"
#include "algo.hpp"
#include <vector>
namespace dc {
/**
* @brief The size (width and height) for a Block inside an image.
* This is used everywhere and can be changed if needed.
*/
static constexpr uint16_t BlockSize = 4u;
static constexpr uint16_t MacroBlockSize = 16u;
class Frame;
/**
* @brief The Block class
* Represents a block, linked to the reader/writer stream,
* and can be used to perform Block-level operations.
*
* @tparam size
* The used Block size.
*/
template<size_t size = dc::BlockSize>
class Block {
private:
uint8_t *matrix[size];
double expanded[size * size];
std::vector<algo::RLE_data_t*> *rle_Data;
algo::MER_level_t mvec_this;
algo::MER_level_t mvec;
public:
Block(uint8_t *row_offset_list[]);
Block(uint8_t *row_offset_list[], int16_t x, int16_t y);
~Block(void);
void expand(void) const;
void expandDifferences(void) const;
// Microblocks
void processDCTDivQ(const double m[]);
void processIDCTMulQ(const double m[]);
void createRLESequence(void);
// Macroblocks
void updateRows(uint8_t *row_offset_list[]);
inline uint8_t* getRow(size_t row) const {
return this->matrix[row];
}
inline double* getExpandedRow(size_t row) {
return &this->expanded[row * size];
}
size_t relativeAbsDifferenceWith(const dc::Block<dc::MacroBlockSize>&);
void expandDifferenceWith(const dc::Block<dc::MacroBlockSize>&);
void processFindMotionOffset(dc::Frame * const ref_frame);
inline algo::MER_level_t getCoord(void) const {
return this->mvec_this;
}
inline algo::MER_level_t getCoordAfterMotion(void) const {
return algo::MER_level_t {
0,
static_cast<int16_t>(this->mvec_this.x0 + this->mvec.x0),
static_cast<int16_t>(this->mvec_this.y0 + this->mvec.y0),
nullptr
};
}
inline bool isDifferentCoord(const int16_t& x, const int16_t& y) const {
return this->mvec_this.x0 != x
|| this->mvec_this.y0 != y;
}
inline bool isDifferentCoord(const algo::MER_level_t& other) const {
return this->isDifferentCoord(other.x0, other.y0);
}
inline bool isDifferentBlock(const dc::Block<dc::MacroBlockSize>& other) const {
return this->isDifferentCoord(other.getCoord());
}
void copyBlockMatrixTo(dc::Block<size>&) const;
void loadFromReferenceStream(util::BitStreamReader&, dc::Frame * const);
size_t streamSize(void) const;
void streamEncoded(util::BitStreamWriter&, bool) const;
void streamMVec(util::BitStreamWriter&) const;
void loadFromStream(util::BitStreamReader&, bool);
void printZigzag(void) const;
void printRLE(void) const;
void printExpanded(void) const;
void printMatrix(void) const;
static void CreateZigZagLUT(void);
static void CreateMERLUT(const uint16_t &merange);
static void DestroyMERLUT(void);
static constexpr size_t SIZE_LEN_BITS = 4; ///< The amount of bits to use to represent the bit length of values inside the Block.
};
extern template class dc::Block<dc::BlockSize>;
extern template class dc::Block<dc::MacroBlockSize>;
using MicroBlock = dc::Block<dc::BlockSize>;
using MacroBlock = dc::Block<dc::MacroBlockSize>;
}
#endif // BLOCK_HPP