Coverage Report

Created: 2025-07-23 09:13

/src/gdal/frmts/mrf/BitMask2D.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright 2016-2017 Esri
3
Licensed under the Apache License, Version 2.0 (the "License");
4
you may not use this file except in compliance with the License.
5
You may obtain a copy of the License at
6
http://www.apache.org/licenses/LICENSE-2.0
7
Unless required by applicable law or agreed to in writing, software
8
distributed under the License is distributed on an "AS IS" BASIS,
9
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
See the License for the specific language governing permissions and
11
limitations under the License.
12
13
Contributors:  Lucian Plesea
14
*/
15
16
/*
17
18
A 2D bitmask stored in 4x4 or 8x8 units
19
While it is a template over unit type, the only valid types are
20
unsigned 16bit and unsigned 64bit
21
22
Obviously not thread safe while any bit gets modified
23
24
*/
25
#if !defined(BITMASK2D_H)
26
#define BITMASK2D_H
27
#include <vector>
28
#include <stdexcept>
29
30
// For CPL_MSB and swap functions
31
#include "cpl_port.h"
32
33
#include "marfa.h"
34
#if defined(PACKER)
35
#include "Packer.h"
36
#endif
37
38
NAMESPACE_MRF_START
39
40
// integer sqrt at compile time
41
// N is the number, M is the number of refining iterations
42
template <int N, int M = 4> struct Sqrt
43
{
44
    static const int value =
45
        (Sqrt<N, M - 1>::value + N / Sqrt<N, M - 1>::value) / 2;
46
};
47
48
// End condition
49
template <int N> struct Sqrt<N, 0>
50
{
51
    static const int value = N / 2;
52
};
53
54
// Round up division by N
55
template <unsigned int N> static int Chunks(int x)
56
1.08k
{
57
1.08k
    return 1 + (x - 1) / N;
58
1.08k
}
JPEG_band.cpp:int GDAL_MRF::Chunks<8u>(int)
Line
Count
Source
56
1.08k
{
57
1.08k
    return 1 + (x - 1) / N;
58
1.08k
}
Unexecuted instantiation: JPEG12_band.cpp:int GDAL_MRF::Chunks<8u>(int)
59
60
//// These exist in C++11, so we name them with upper case
61
// template < typename T1, typename T2 > struct Is_Same {
62
//     enum { value = false }; // is_same represents a bool.
63
//     typedef Is_Same<T1, T2> type; // to qualify as a metafunction.
64
// };
65
//
66
//
67
////// Specialization
68
// template < typename T > struct Is_Same<T,T> {
69
//     enum { value = true };
70
//     typedef Is_Same<T, T> type;
71
// };
72
//
73
74
// linear size of storage unit, 4 or 8
75
12.7M
#define TGSIZE Sqrt<sizeof(T) * 8>::value
76
77
template <typename T = unsigned long long> class BitMap2D
78
{
79
  public:
80
    // Initialized to all bits set
81
362
    BitMap2D(unsigned int width, unsigned int height) : _w(width), _h(height)
82
362
    {
83
        // Prevent creation of bitmasks using any other types
84
85
        // Uncomment these statements to enforce only 64 and 16 bit units
86
        // They work but generate warnings on some compilers
87
        // Is_Same<T, unsigned long long>::type a;
88
        // Is_Same<T, unsigned short>::type b;
89
        // if (!(a.value || b.value))
90
        //   throw std::out_of_range("Only bitmap units of unsigned 16 and 64
91
        //   bits work");
92
93
        // Precalculate row size in storage units, for speed
94
362
        _lw = Chunks<TGSIZE>(_w);
95
        // Defaults to all set
96
362
        init(~(T)0);
97
362
#if defined(PACKER)
98
362
        _packer = nullptr;
99
362
#endif
100
362
    }
101
102
    int getWidth() const
103
25
    {
104
25
        return _w;
105
25
    }
106
107
    int getHeight() const
108
25
    {
109
25
        return _h;
110
25
    }
111
112
    // Size in bytes
113
    size_t size() const
114
252
    {
115
252
        return _bits.size() * sizeof(T);
116
252
    }
117
118
    // Returns the condition of a specific bit
119
    bool isSet(int x, int y) const
120
2.54M
    {
121
2.54M
        return 0 != (_bits[_idx(x, y)] & _bitmask(x, y));
122
2.54M
    }
123
124
    void set(int x, int y)
125
    {
126
        _bits[_idx(x, y)] |= _bitmask(x, y);
127
    }
128
129
    void clear(int x, int y)
130
0
    {
131
0
        _bits[_idx(x, y)] &= ~_bitmask(x, y);
132
0
    }
133
134
    // Set a location bit to true or false
135
    void assign(int x, int y, bool val = true)
136
    {
137
        if (val)
138
            set(x, y);
139
        else
140
            clear(x, y);
141
    }
142
143
    // Flip a bit
144
    void flip(int x, int y)
145
    {
146
        _bits[_idx(x, y)] ^= _bitmask(x, y);
147
    }
148
149
    // Set all units to same bit pattern by unit
150
    // Use init(~(T)0)) for all set
151
    void init(T val)
152
362
    {
153
362
        _bits.assign(
154
362
            static_cast<size_t>(Chunks<TGSIZE>(_w)) * Chunks<TGSIZE>(_h), val);
155
362
    }
156
157
    // Support for store and load
158
#if defined(PACKER)
159
160
    void set_packer(Packer *packer)
161
362
    {
162
362
        _packer = packer;
163
362
    }
164
165
    int store(storage_manager *dst)
166
0
    {
167
0
        int result;
168
0
        storage_manager src = {reinterpret_cast<char *>(&_bits[0]), size()};
169
        // Store the bytes in little endian format
170
0
        swab();
171
0
        if (_packer)
172
0
            result = _packer->store(&src, dst);
173
0
        else
174
0
            result = Packer().store(&src, dst);
175
0
        swab();
176
0
        return result;
177
0
    }
178
179
    int load(storage_manager *src)
180
252
    {
181
252
        int result;
182
252
        storage_manager dst = {reinterpret_cast<char *>(&_bits[0]), size()};
183
252
        if (_packer)
184
252
            result = _packer->load(src, &dst);
185
0
        else
186
0
            result = Packer().load(src, &dst);
187
252
        swab();
188
252
        return result;
189
252
    }
190
#endif
191
192
  private:
193
    // unit index
194
    unsigned int _idx(int x, int y) const
195
2.54M
    {
196
2.54M
        return _lw * (y / TGSIZE) + x / TGSIZE;
197
2.54M
    }
198
199
    // one bit mask within a unit
200
    static T _bitmask(int x, int y)
201
2.54M
    {
202
2.54M
        return static_cast<T>(1) << (TGSIZE * (y % TGSIZE) + x % TGSIZE);
203
2.54M
    }
204
205
#if defined(PACKER)
206
// Swap bytes of storage units within the bitmap to low endian
207
#if defined(CPL_LSB)
208
    static void swab()
209
252
    {
210
252
    }
211
#else
212
    void swab()
213
    {
214
        for (size_t i = 0; i < _bits.size(); i++)
215
        {
216
            if (sizeof(T) == sizeof(GUIntBig))
217
            {
218
                CPL_SWAP64PTR(reinterpret_cast<GUIntBig *>(&_bits[i]));
219
            }
220
            else
221
            {
222
                CPL_SWAP16PTR(reinterpret_cast<GUInt16 *>(&_bits[i]));
223
            }
224
        }
225
    }
226
#endif
227
228
    // Class that provides export and import capabilities, not owned
229
    Packer *_packer;
230
#endif
231
232
    // bit storage vector
233
    std::vector<T> _bits;
234
    // width and height of bitmap
235
    unsigned int _w, _h;
236
    // Line size in linear chunks
237
    unsigned int _lw;
238
};
239
240
#undef TGSIZE
241
NAMESPACE_MRF_END
242
#endif