Line data Source code
1 : /*
2 : Copyright 2015 Esri
3 :
4 : Licensed under the Apache License, Version 2.0 (the "License");
5 : you may not use this file except in compliance with the License.
6 : You may obtain a copy of the License at
7 :
8 : http://www.apache.org/licenses/LICENSE-2.0
9 :
10 : Unless required by applicable law or agreed to in writing, software
11 : distributed under the License is distributed on an "AS IS" BASIS,
12 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : See the License for the specific language governing permissions and
14 : limitations under the License.
15 :
16 : A local copy of the license and additional notices are located with the
17 : source distribution at:
18 :
19 : http://github.com/Esri/lerc/
20 :
21 : Contributors: Thomas Maurer
22 : */
23 :
24 : #ifndef BITSTUFFER2_H
25 : #define BITSTUFFER2_H
26 :
27 : #include <vector>
28 : #include <cstring>
29 : #include <utility>
30 : #include "Defines.h"
31 :
32 : NAMESPACE_LERC_START
33 :
34 : /** Bit stuffer, for writing unsigned int arrays compressed lossless
35 : *
36 : */
37 :
38 : class BitStuffer2
39 : {
40 : public:
41 11903 : BitStuffer2() {}
42 11903 : virtual ~BitStuffer2() {}
43 :
44 : // dst buffer is already allocated. byte ptr is moved like a file pointer.
45 : bool EncodeSimple(Byte** ppByte, const std::vector<unsigned int>& dataVec, int lerc2Version) const;
46 : bool EncodeLut(Byte** ppByte, const std::vector<std::pair<unsigned int, unsigned int> >& sortedDataVec, int lerc2Version) const;
47 : bool Decode(const Byte** ppByte, size_t& nBytesRemaining, std::vector<unsigned int>& dataVec, size_t maxElementCount, int lerc2Version) const;
48 :
49 : static unsigned int ComputeNumBytesNeededSimple(unsigned int numElem, unsigned int maxElem);
50 : static unsigned int ComputeNumBytesNeededLut(const std::vector<std::pair<unsigned int, unsigned int> >& sortedDataVec, bool& doLut);
51 :
52 : private:
53 : mutable std::vector<unsigned int> m_tmpLutVec, m_tmpIndexVec, m_tmpBitStuffVec;
54 :
55 : static void BitStuff_Before_Lerc2v3(Byte** ppByte, const std::vector<unsigned int>& dataVec, int numBits);
56 : bool BitUnStuff_Before_Lerc2v3(const Byte** ppByte, size_t& nBytesRemaining, std::vector<unsigned int>& dataVec, unsigned int numElements, int numBits) const;
57 : void BitStuff(Byte** ppByte, const std::vector<unsigned int>& dataVec, int numBits) const;
58 : bool BitUnStuff(const Byte** ppByte, size_t& nBytesRemaining, std::vector<unsigned int>& dataVec, unsigned int numElements, int numBits) const;
59 :
60 : static bool EncodeUInt(Byte** ppByte, unsigned int k, int numBytes); // numBytes = 1, 2, or 4
61 : static bool DecodeUInt(const Byte** ppByte, size_t& nBytesRemaining, unsigned int& k, int numBytes);
62 1747160 : static int NumBytesUInt(unsigned int k) { return (k < 256) ? 1 : (k < (1 << 16)) ? 2 : 4; }
63 : static unsigned int NumTailBytesNotNeeded(unsigned int numElem, int numBits);
64 : };
65 :
66 : // -------------------------------------------------------------------------- ;
67 :
68 64555 : inline unsigned int BitStuffer2::ComputeNumBytesNeededSimple(unsigned int numElem, unsigned int maxElem)
69 : {
70 64555 : int numBits = 0;
71 426568 : while ((numBits < 32) && (maxElem >> numBits))
72 362013 : numBits++;
73 64555 : return 1 + NumBytesUInt(numElem) + ((numElem * numBits + 7) >> 3);
74 : }
75 :
76 : // -------------------------------------------------------------------------- ;
77 :
78 263465 : inline bool BitStuffer2::EncodeUInt(Byte** ppByte, unsigned int k, int numBytes)
79 : {
80 263465 : Byte* ptr = *ppByte;
81 :
82 263465 : if (numBytes == 1)
83 258238 : *ptr = (Byte)k;
84 5227 : else if (numBytes == 2)
85 : {
86 5227 : unsigned short kShort = (unsigned short)k;
87 5227 : memcpy(ptr, &kShort, sizeof(unsigned short));
88 : }
89 0 : else if (numBytes == 4)
90 0 : memcpy(ptr, &k, sizeof(unsigned int));
91 : else
92 0 : return false;
93 :
94 263465 : *ppByte += numBytes;
95 263465 : return true;
96 : }
97 :
98 : // -------------------------------------------------------------------------- ;
99 :
100 113518 : inline bool BitStuffer2::DecodeUInt(const Byte** ppByte, size_t& nBytesRemaining, unsigned int& k, int numBytes)
101 : {
102 113518 : if (nBytesRemaining < (size_t)numBytes)
103 0 : return false;
104 :
105 113518 : const Byte* ptr = *ppByte;
106 :
107 113518 : if (numBytes == 1)
108 111759 : k = *ptr;
109 1759 : else if (numBytes == 2)
110 : {
111 : unsigned short s;
112 1759 : memcpy(&s, ptr, sizeof(unsigned short));
113 1759 : k = s;
114 : }
115 0 : else if (numBytes == 4)
116 0 : memcpy(&k, ptr, sizeof(unsigned int));
117 : else
118 0 : return false;
119 :
120 113518 : *ppByte += numBytes;
121 113518 : nBytesRemaining -= numBytes;
122 113518 : return true;
123 : }
124 :
125 : // -------------------------------------------------------------------------- ;
126 :
127 672863 : inline unsigned int BitStuffer2::NumTailBytesNotNeeded(unsigned int numElem, int numBits)
128 : {
129 672863 : int numBitsTail = ((unsigned long long)numElem * numBits) & 31;
130 672863 : int numBytesTail = (numBitsTail + 7) >> 3;
131 672863 : return (numBytesTail > 0) ? 4 - numBytesTail : 0;
132 : }
133 :
134 : // -------------------------------------------------------------------------- ;
135 :
136 : NAMESPACE_LERC_END
137 : #endif
|