Coverage Report

Created: 2024-09-11 06:42

/src/gfwx-fuzzers/gfwx.h
Line
Count
Source (jump to first uncovered line)
1
//  Good, Fast Wavelet Codec "GFWX" v1
2
//  ----------------------------------
3
//  December 1, 2015 [patched on Oct 20, 2017]
4
//  Author: Graham Fyffe <gfyffe@gmail.com> or <fyffe@google.com>, and Google, Inc.
5
//  Website: www.gfwx.org
6
//  Features:
7
//  - FAST
8
//  - compression ratio similar to JPEG 2000
9
//  - under 1000 lines of code, with no external libraries
10
//  - 100% lossless at max quality
11
//  - low quality looks interpolated instead of blocky
12
//  - progressive decoding with optional downsampling
13
//  - supports uint8_t, int8_t, uint16_t, int16_t
14
//  - supports 1 to 65536 interleaved channels
15
//  - supports 1 to 65536 non-interleaved layers
16
//  - optional Bayer mode to compress Bayer data more
17
//  - optional chroma downsampling, even in Bayer mode
18
//  - optional user-programmable color/channel transform
19
//  - optional slightly less fast mode to compress more
20
//  - imageData can be any class with a pointer-like interface
21
//  - thoroughly tested using several pictures of cats
22
//
23
//  GFWX is released under the 3-clause BSD license:
24
//
25
//  Copyright (c) 2015, University of Southern California. All rights reserved. Redistribution and use in source and binary forms,
26
//  with or without modification, are permitted provided that the following conditions are met:
27
//
28
//  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
29
//
30
//  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in
31
//     the documentation and/or other materials provided with the distribution.
32
//
33
//  3. Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from
34
//     this software without specific prior written permission.
35
//
36
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37
//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
38
//  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39
//  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40
//  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41
//  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
43
#pragma once
44
#include <algorithm>
45
#include <cstddef>
46
#include <cstdint>
47
#include <cstdlib>
48
#include <limits>
49
#include <type_traits>
50
#include <utility>
51
#include <vector>
52
#if defined(_OPENMP) && defined(_MSC_VER)
53
#define OMP_PARALLEL_FOR(X) __pragma(omp parallel for schedule(dynamic, X))
54
#elif defined(_OPENMP)
55
#include <omp.h>
56
#define STR(X) #X
57
#define STRINGIFY(X) STR(X)
58
#define TWO_ARGUMENTS(X,Y,Z) X(Y, Z)
59
#define OMP_PARALLEL_FOR(X) _Pragma(STRINGIFY(TWO_ARGUMENTS(omp parallel for schedule, dynamic, X)))
60
#else
61
#define OMP_PARALLEL_FOR(X)
62
#endif
63
64
namespace GFWX
65
{
66
  enum
67
  {
68
    QualityMax = 1024,    // compress with QualityMax for 100% lossless, or less than QualityMax for lossy
69
    ThreadIterations = 64,  // OMP settings tuned on my machine with large images
70
    BitDepthAuto = 0, BlockDefault = 7, BlockMax = 30,
71
    FilterLinear = 0, FilterCubic = 1, QuantizationScalar = 0, EncoderTurbo = 0, EncoderFast = 1, EncoderContextual = 2,
72
    IntentGeneric = 0, IntentMono = 1, IntentBayerRGGB = 2, IntentBayerBGGR = 3, IntentBayerGRBG = 4, IntentBayerGBRG = 5, IntentBayerGeneric = 6,
73
    IntentRGB = 7, IntentRGBA = 8, IntentRGBApremult = 9, IntentBGR = 10, IntentBGRA = 11, IntentBGRApremult = 12, IntentCMYK = 13,
74
    ResultOk = 0, ErrorOverflow = -1, ErrorMalformed = -2, ErrorTypeMismatch = -3
75
  };
76
77
  struct Header // use the empty constructor to fetch headers before decompressing, and use the parameterized constructor when compressing
78
  {
79
    int sizex, sizey, layers, channels, bitDepth, quality, chromaScale, blockSize, filter, quantization, encoder, intent, version, isSigned;
80
16
    Header() {}
81
    Header(int sizex, int sizey, int layers, int channels, int bitDepth,
82
      int quality, int chromaScale, int blockSize, int filter, int quantization, int encoder, int intent)
83
      : sizex(sizex), sizey(sizey), layers(layers), channels(channels), bitDepth(bitDepth), quality(std::max(1, std::min(int(QualityMax), quality))),
84
      chromaScale(std::max(1, std::min(256, chromaScale))), blockSize(std::min(30, std::max(2, blockSize))), filter(std::min(255, filter)),
85
2.96k
      quantization(std::min(255, quantization)), encoder(std::min(255, encoder)), intent(std::min(255, intent)) {}
86
    size_t bufferSize() const
87
25
    {
88
25
      size_t const part1 = static_cast<size_t>(sizex) * sizey;
89
25
      size_t const part2 = static_cast<size_t>(channels) * layers * ((bitDepth + 7) / 8);
90
25
      return std::log(part1) + std::log(part2) > std::log(std::numeric_limits<size_t>::max() - 1) ? 0 : part1 * part2;
91
25
    }
92
  };
93
94
  template<typename T> struct Image // handy wrapper for 2D image data
95
  {
96
    T * data;
97
    int sizex, sizey;
98
3.48M
    Image(T * data, int sizex, int sizey) : data(data), sizex(sizex), sizey(sizey) {}
99
703M
    T * operator[] (int y) { return data + static_cast<size_t>(y) * sizex; }
100
  };
101
102
  struct Bits // handy wrapper for treating an array of unsigned ints as a bit stream
103
  {
104
    uint32_t * buffer, * bufferEnd;
105
    uint32_t writeCache;
106
    int indexBits;  // -1 indicates buffer overflow
107
16.2k
    Bits(uint32_t * buffer, uint32_t * bufferEnd) : buffer(buffer), bufferEnd(bufferEnd), writeCache(0), indexBits(0) {}
108
    uint32_t getBits(int bits)
109
9.81M
    {
110
9.81M
      int newBits = indexBits + bits;
111
9.81M
      if (buffer == bufferEnd)
112
67.8k
        return indexBits = -1;  // signify overflow
113
9.74M
      uint32_t x = *buffer << indexBits;
114
9.74M
      if (newBits >= 32)
115
486k
      {
116
486k
        ++ buffer;
117
486k
        if ((newBits -= 32) > 0)
118
9.12k
        {
119
9.12k
          if (buffer == bufferEnd)
120
1
            return indexBits = -1;  // signify overflow
121
9.12k
          x |= *buffer >> (32 - indexBits);
122
9.12k
        }
123
486k
      }
124
9.74M
      indexBits = newBits;
125
9.74M
      return x >> (32 - bits);
126
9.74M
    }
127
    void putBits(uint32_t x, int bits)
128
61.1M
    {
129
61.1M
      int newBits = indexBits + bits;
130
61.1M
      if (buffer == bufferEnd)
131
10.6M
        newBits = -1;  // signify overflow
132
50.5M
      else if (newBits < 32)
133
38.7M
        (writeCache <<= bits) |= x;
134
11.7M
      else if (bits == 32 && newBits == 32)
135
13.5k
      {
136
13.5k
        newBits = 0;
137
13.5k
        *(buffer ++) = x;
138
13.5k
      }
139
11.7M
      else
140
11.7M
      {
141
11.7M
        newBits -= 32;
142
11.7M
        *(buffer ++) = (writeCache << (bits - newBits)) | (x >> newBits);
143
11.7M
        writeCache = x;
144
11.7M
      }
145
61.1M
      indexBits = newBits;
146
61.1M
    }
147
    uint32_t getZeros(uint32_t maxZeros)
148
5.40M
    {
149
5.40M
      int newBits = indexBits;
150
5.40M
      if (buffer == bufferEnd)
151
103k
        return indexBits = -1;  // signify overflow
152
5.30M
      uint32_t b = *buffer;
153
5.30M
      uint32_t x = 0;
154
7.40M
      while (true)
155
7.40M
      {
156
7.40M
        if (newBits == 31)
157
217k
        {
158
217k
          ++ buffer;
159
217k
          if ((b & 1u) || (++ x == maxZeros))
160
161k
          {
161
161k
            indexBits = 0;
162
161k
            return x;
163
161k
          }
164
55.9k
          if (buffer == bufferEnd)
165
1
            return indexBits = -1;  // signify overflow
166
55.9k
          b = *buffer;
167
55.9k
          newBits = 0;
168
55.9k
          continue;
169
55.9k
        }
170
7.19M
        if (((b << newBits) & (1u << 31)) || (++ x == maxZeros))
171
5.14M
        {
172
5.14M
          indexBits = newBits + 1;
173
5.14M
          return x;
174
5.14M
        }
175
2.04M
        ++ newBits;
176
2.04M
      }
177
5.30M
    }
178
    void flushWriteWord() // [NOTE] does not clear overflow
179
3.47M
    {
180
3.47M
      putBits(0, (32 - indexBits) % 32);
181
3.47M
    }
182
    void flushReadWord()  // [NOTE] does not clear overflow
183
12
    {
184
12
      if (indexBits <= 0)
185
5
        return;
186
7
      ++ buffer;
187
7
      indexBits = 0;
188
7
    }
189
  };
190
191
  template<int pot> void unsignedCode(uint32_t x, Bits & stream)  // limited length power-of-two Golomb-Rice code
192
45.6M
  {
193
45.6M
    uint32_t const y = x >> (pot);
194
45.6M
    if (y >= 12)
195
13.4M
    {
196
13.4M
      stream.putBits(0, 12);  // escape to larger code
197
13.4M
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
13.4M
    }
199
32.2M
    else
200
32.2M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
45.6M
  }
void GFWX::unsignedCode<2>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
754k
  {
193
754k
    uint32_t const y = x >> (pot);
194
754k
    if (y >= 12)
195
73.9k
    {
196
73.9k
      stream.putBits(0, 12);  // escape to larger code
197
73.9k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
73.9k
    }
199
680k
    else
200
680k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
754k
  }
void GFWX::unsignedCode<6>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
73.9k
  {
193
73.9k
    uint32_t const y = x >> (pot);
194
73.9k
    if (y >= 12)
195
11.1k
    {
196
11.1k
      stream.putBits(0, 12);  // escape to larger code
197
11.1k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
11.1k
    }
199
62.7k
    else
200
62.7k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
73.9k
  }
void GFWX::unsignedCode<10>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
11.1k
  {
193
11.1k
    uint32_t const y = x >> (pot);
194
11.1k
    if (y >= 12)
195
897
    {
196
897
      stream.putBits(0, 12);  // escape to larger code
197
897
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
897
    }
199
10.2k
    else
200
10.2k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
11.1k
  }
void GFWX::unsignedCode<14>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
897
  {
193
897
    uint32_t const y = x >> (pot);
194
897
    if (y >= 12)
195
35
    {
196
35
      stream.putBits(0, 12);  // escape to larger code
197
35
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
35
    }
199
862
    else
200
862
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
897
  }
void GFWX::unsignedCode<18>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
35
  {
193
35
    uint32_t const y = x >> (pot);
194
35
    if (y >= 12)
195
0
    {
196
0
      stream.putBits(0, 12);  // escape to larger code
197
0
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
0
    }
199
35
    else
200
35
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
35
  }
Unexecuted instantiation: void GFWX::unsignedCode<22>(unsigned int, GFWX::Bits&)
Unexecuted instantiation: void GFWX::unsignedCode<24>(unsigned int, GFWX::Bits&)
void GFWX::unsignedCode<1>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
13.6M
  {
193
13.6M
    uint32_t const y = x >> (pot);
194
13.6M
    if (y >= 12)
195
5.21M
    {
196
5.21M
      stream.putBits(0, 12);  // escape to larger code
197
5.21M
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
5.21M
    }
199
8.47M
    else
200
8.47M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
13.6M
  }
void GFWX::unsignedCode<5>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
5.21M
  {
193
5.21M
    uint32_t const y = x >> (pot);
194
5.21M
    if (y >= 12)
195
2.16M
    {
196
2.16M
      stream.putBits(0, 12);  // escape to larger code
197
2.16M
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
2.16M
    }
199
3.05M
    else
200
3.05M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
5.21M
  }
void GFWX::unsignedCode<9>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
2.16M
  {
193
2.16M
    uint32_t const y = x >> (pot);
194
2.16M
    if (y >= 12)
195
11.5k
    {
196
11.5k
      stream.putBits(0, 12);  // escape to larger code
197
11.5k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
11.5k
    }
199
2.15M
    else
200
2.15M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
2.16M
  }
void GFWX::unsignedCode<13>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
11.5k
  {
193
11.5k
    uint32_t const y = x >> (pot);
194
11.5k
    if (y >= 12)
195
56
    {
196
56
      stream.putBits(0, 12);  // escape to larger code
197
56
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
56
    }
199
11.4k
    else
200
11.4k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
11.5k
  }
void GFWX::unsignedCode<17>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
56
  {
193
56
    uint32_t const y = x >> (pot);
194
56
    if (y >= 12)
195
0
    {
196
0
      stream.putBits(0, 12);  // escape to larger code
197
0
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
0
    }
199
56
    else
200
56
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
56
  }
Unexecuted instantiation: void GFWX::unsignedCode<21>(unsigned int, GFWX::Bits&)
void GFWX::unsignedCode<3>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
1.09M
  {
193
1.09M
    uint32_t const y = x >> (pot);
194
1.09M
    if (y >= 12)
195
130k
    {
196
130k
      stream.putBits(0, 12);  // escape to larger code
197
130k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
130k
    }
199
963k
    else
200
963k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
1.09M
  }
void GFWX::unsignedCode<7>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
130k
  {
193
130k
    uint32_t const y = x >> (pot);
194
130k
    if (y >= 12)
195
11.0k
    {
196
11.0k
      stream.putBits(0, 12);  // escape to larger code
197
11.0k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
11.0k
    }
199
119k
    else
200
119k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
130k
  }
void GFWX::unsignedCode<11>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
11.0k
  {
193
11.0k
    uint32_t const y = x >> (pot);
194
11.0k
    if (y >= 12)
195
176
    {
196
176
      stream.putBits(0, 12);  // escape to larger code
197
176
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
176
    }
199
10.8k
    else
200
10.8k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
11.0k
  }
void GFWX::unsignedCode<15>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
176
  {
193
176
    uint32_t const y = x >> (pot);
194
176
    if (y >= 12)
195
0
    {
196
0
      stream.putBits(0, 12);  // escape to larger code
197
0
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
0
    }
199
176
    else
200
176
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
176
  }
Unexecuted instantiation: void GFWX::unsignedCode<19>(unsigned int, GFWX::Bits&)
Unexecuted instantiation: void GFWX::unsignedCode<23>(unsigned int, GFWX::Bits&)
void GFWX::unsignedCode<4>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
14.3M
  {
193
14.3M
    uint32_t const y = x >> (pot);
194
14.3M
    if (y >= 12)
195
5.15M
    {
196
5.15M
      stream.putBits(0, 12);  // escape to larger code
197
5.15M
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
5.15M
    }
199
9.21M
    else
200
9.21M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
14.3M
  }
void GFWX::unsignedCode<8>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
5.15M
  {
193
5.15M
    uint32_t const y = x >> (pot);
194
5.15M
    if (y >= 12)
195
77.5k
    {
196
77.5k
      stream.putBits(0, 12);  // escape to larger code
197
77.5k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
77.5k
    }
199
5.07M
    else
200
5.07M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
5.15M
  }
void GFWX::unsignedCode<12>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
77.5k
  {
193
77.5k
    uint32_t const y = x >> (pot);
194
77.5k
    if (y >= 12)
195
92
    {
196
92
      stream.putBits(0, 12);  // escape to larger code
197
92
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
92
    }
199
77.4k
    else
200
77.4k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
77.5k
  }
void GFWX::unsignedCode<16>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
92
  {
193
92
    uint32_t const y = x >> (pot);
194
92
    if (y >= 12)
195
0
    {
196
0
      stream.putBits(0, 12);  // escape to larger code
197
0
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
0
    }
199
92
    else
200
92
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
92
  }
Unexecuted instantiation: void GFWX::unsignedCode<20>(unsigned int, GFWX::Bits&)
void GFWX::unsignedCode<0>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
2.92M
  {
193
2.92M
    uint32_t const y = x >> (pot);
194
2.92M
    if (y >= 12)
195
604k
    {
196
604k
      stream.putBits(0, 12);  // escape to larger code
197
604k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
604k
    }
199
2.31M
    else
200
2.31M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
2.92M
  }
202
203
  template<int pot> uint32_t unsignedDecode(Bits & stream)
204
5.40M
  {
205
5.40M
    uint32_t x = stream.getZeros(12);
206
5.40M
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
5.40M
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
5.40M
  }
unsigned int GFWX::unsignedDecode<2>(GFWX::Bits&)
Line
Count
Source
204
5.03M
  {
205
5.03M
    uint32_t x = stream.getZeros(12);
206
5.03M
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
5.03M
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
5.03M
  }
unsigned int GFWX::unsignedDecode<6>(GFWX::Bits&)
Line
Count
Source
204
1.02k
  {
205
1.02k
    uint32_t x = stream.getZeros(12);
206
1.02k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.02k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.02k
  }
unsigned int GFWX::unsignedDecode<10>(GFWX::Bits&)
Line
Count
Source
204
967
  {
205
967
    uint32_t x = stream.getZeros(12);
206
967
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
967
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
967
  }
unsigned int GFWX::unsignedDecode<14>(GFWX::Bits&)
Line
Count
Source
204
935
  {
205
935
    uint32_t x = stream.getZeros(12);
206
935
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
935
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
935
  }
unsigned int GFWX::unsignedDecode<18>(GFWX::Bits&)
Line
Count
Source
204
923
  {
205
923
    uint32_t x = stream.getZeros(12);
206
923
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
923
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
923
  }
unsigned int GFWX::unsignedDecode<22>(GFWX::Bits&)
Line
Count
Source
204
918
  {
205
918
    uint32_t x = stream.getZeros(12);
206
918
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
918
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
918
  }
unsigned int GFWX::unsignedDecode<26>(GFWX::Bits&)
Line
Count
Source
204
916
  {
205
916
    uint32_t x = stream.getZeros(12);
206
916
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
916
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
916
  }
unsigned int GFWX::unsignedDecode<30>(GFWX::Bits&)
Line
Count
Source
204
914
  {
205
914
    uint32_t x = stream.getZeros(12);
206
914
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
914
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
914
  }
unsigned int GFWX::unsignedDecode<34>(GFWX::Bits&)
Line
Count
Source
204
914
  {
205
914
    uint32_t x = stream.getZeros(12);
206
914
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
914
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
914
  }
unsigned int GFWX::unsignedDecode<38>(GFWX::Bits&)
Line
Count
Source
204
908
  {
205
908
    uint32_t x = stream.getZeros(12);
206
908
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
908
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
908
  }
unsigned int GFWX::unsignedDecode<42>(GFWX::Bits&)
Line
Count
Source
204
906
  {
205
906
    uint32_t x = stream.getZeros(12);
206
906
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
906
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
906
  }
unsigned int GFWX::unsignedDecode<46>(GFWX::Bits&)
Line
Count
Source
204
904
  {
205
904
    uint32_t x = stream.getZeros(12);
206
904
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
904
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
904
  }
unsigned int GFWX::unsignedDecode<50>(GFWX::Bits&)
Line
Count
Source
204
901
  {
205
901
    uint32_t x = stream.getZeros(12);
206
901
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
901
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
901
  }
unsigned int GFWX::unsignedDecode<54>(GFWX::Bits&)
Line
Count
Source
204
901
  {
205
901
    uint32_t x = stream.getZeros(12);
206
901
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
901
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
901
  }
unsigned int GFWX::unsignedDecode<58>(GFWX::Bits&)
Line
Count
Source
204
901
  {
205
901
    uint32_t x = stream.getZeros(12);
206
901
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
901
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
901
  }
unsigned int GFWX::unsignedDecode<62>(GFWX::Bits&)
Line
Count
Source
204
899
  {
205
899
    uint32_t x = stream.getZeros(12);
206
899
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
899
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
899
  }
unsigned int GFWX::unsignedDecode<66>(GFWX::Bits&)
Line
Count
Source
204
877
  {
205
877
    uint32_t x = stream.getZeros(12);
206
877
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
877
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
877
  }
unsigned int GFWX::unsignedDecode<70>(GFWX::Bits&)
Line
Count
Source
204
875
  {
205
875
    uint32_t x = stream.getZeros(12);
206
875
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
875
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
875
  }
unsigned int GFWX::unsignedDecode<74>(GFWX::Bits&)
Line
Count
Source
204
872
  {
205
872
    uint32_t x = stream.getZeros(12);
206
872
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
872
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
872
  }
unsigned int GFWX::unsignedDecode<78>(GFWX::Bits&)
Line
Count
Source
204
872
  {
205
872
    uint32_t x = stream.getZeros(12);
206
872
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
872
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
872
  }
unsigned int GFWX::unsignedDecode<82>(GFWX::Bits&)
Line
Count
Source
204
872
  {
205
872
    uint32_t x = stream.getZeros(12);
206
872
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
872
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
872
  }
unsigned int GFWX::unsignedDecode<86>(GFWX::Bits&)
Line
Count
Source
204
870
  {
205
870
    uint32_t x = stream.getZeros(12);
206
870
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
870
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
870
  }
unsigned int GFWX::unsignedDecode<90>(GFWX::Bits&)
Line
Count
Source
204
870
  {
205
870
    uint32_t x = stream.getZeros(12);
206
870
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
870
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
870
  }
unsigned int GFWX::unsignedDecode<94>(GFWX::Bits&)
Line
Count
Source
204
864
  {
205
864
    uint32_t x = stream.getZeros(12);
206
864
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
864
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
864
  }
unsigned int GFWX::unsignedDecode<98>(GFWX::Bits&)
Line
Count
Source
204
864
  {
205
864
    uint32_t x = stream.getZeros(12);
206
864
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
864
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
864
  }
unsigned int GFWX::unsignedDecode<102>(GFWX::Bits&)
Line
Count
Source
204
864
  {
205
864
    uint32_t x = stream.getZeros(12);
206
864
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
864
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
864
  }
unsigned int GFWX::unsignedDecode<106>(GFWX::Bits&)
Line
Count
Source
204
863
  {
205
863
    uint32_t x = stream.getZeros(12);
206
863
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
863
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
863
  }
unsigned int GFWX::unsignedDecode<110>(GFWX::Bits&)
Line
Count
Source
204
863
  {
205
863
    uint32_t x = stream.getZeros(12);
206
863
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
863
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
863
  }
unsigned int GFWX::unsignedDecode<1>(GFWX::Bits&)
Line
Count
Source
204
66.2k
  {
205
66.2k
    uint32_t x = stream.getZeros(12);
206
66.2k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
66.2k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
66.2k
  }
unsigned int GFWX::unsignedDecode<5>(GFWX::Bits&)
Line
Count
Source
204
9.02k
  {
205
9.02k
    uint32_t x = stream.getZeros(12);
206
9.02k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
9.02k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
9.02k
  }
unsigned int GFWX::unsignedDecode<9>(GFWX::Bits&)
Line
Count
Source
204
7.86k
  {
205
7.86k
    uint32_t x = stream.getZeros(12);
206
7.86k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
7.86k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
7.86k
  }
unsigned int GFWX::unsignedDecode<13>(GFWX::Bits&)
Line
Count
Source
204
6.92k
  {
205
6.92k
    uint32_t x = stream.getZeros(12);
206
6.92k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
6.92k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
6.92k
  }
unsigned int GFWX::unsignedDecode<17>(GFWX::Bits&)
Line
Count
Source
204
6.66k
  {
205
6.66k
    uint32_t x = stream.getZeros(12);
206
6.66k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
6.66k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
6.66k
  }
unsigned int GFWX::unsignedDecode<21>(GFWX::Bits&)
Line
Count
Source
204
5.91k
  {
205
5.91k
    uint32_t x = stream.getZeros(12);
206
5.91k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
5.91k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
5.91k
  }
unsigned int GFWX::unsignedDecode<25>(GFWX::Bits&)
Line
Count
Source
204
5.69k
  {
205
5.69k
    uint32_t x = stream.getZeros(12);
206
5.69k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
5.69k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
5.69k
  }
unsigned int GFWX::unsignedDecode<29>(GFWX::Bits&)
Line
Count
Source
204
5.53k
  {
205
5.53k
    uint32_t x = stream.getZeros(12);
206
5.53k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
5.53k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
5.53k
  }
unsigned int GFWX::unsignedDecode<33>(GFWX::Bits&)
Line
Count
Source
204
5.40k
  {
205
5.40k
    uint32_t x = stream.getZeros(12);
206
5.40k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
5.40k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
5.40k
  }
unsigned int GFWX::unsignedDecode<37>(GFWX::Bits&)
Line
Count
Source
204
5.06k
  {
205
5.06k
    uint32_t x = stream.getZeros(12);
206
5.06k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
5.06k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
5.06k
  }
unsigned int GFWX::unsignedDecode<41>(GFWX::Bits&)
Line
Count
Source
204
4.93k
  {
205
4.93k
    uint32_t x = stream.getZeros(12);
206
4.93k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
4.93k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
4.93k
  }
unsigned int GFWX::unsignedDecode<45>(GFWX::Bits&)
Line
Count
Source
204
4.87k
  {
205
4.87k
    uint32_t x = stream.getZeros(12);
206
4.87k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
4.87k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
4.87k
  }
unsigned int GFWX::unsignedDecode<49>(GFWX::Bits&)
Line
Count
Source
204
4.77k
  {
205
4.77k
    uint32_t x = stream.getZeros(12);
206
4.77k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
4.77k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
4.77k
  }
unsigned int GFWX::unsignedDecode<53>(GFWX::Bits&)
Line
Count
Source
204
4.68k
  {
205
4.68k
    uint32_t x = stream.getZeros(12);
206
4.68k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
4.68k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
4.68k
  }
unsigned int GFWX::unsignedDecode<57>(GFWX::Bits&)
Line
Count
Source
204
4.59k
  {
205
4.59k
    uint32_t x = stream.getZeros(12);
206
4.59k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
4.59k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
4.59k
  }
unsigned int GFWX::unsignedDecode<61>(GFWX::Bits&)
Line
Count
Source
204
4.51k
  {
205
4.51k
    uint32_t x = stream.getZeros(12);
206
4.51k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
4.51k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
4.51k
  }
unsigned int GFWX::unsignedDecode<65>(GFWX::Bits&)
Line
Count
Source
204
4.43k
  {
205
4.43k
    uint32_t x = stream.getZeros(12);
206
4.43k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
4.43k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
4.43k
  }
unsigned int GFWX::unsignedDecode<69>(GFWX::Bits&)
Line
Count
Source
204
4.12k
  {
205
4.12k
    uint32_t x = stream.getZeros(12);
206
4.12k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
4.12k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
4.12k
  }
unsigned int GFWX::unsignedDecode<73>(GFWX::Bits&)
Line
Count
Source
204
3.34k
  {
205
3.34k
    uint32_t x = stream.getZeros(12);
206
3.34k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
3.34k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
3.34k
  }
unsigned int GFWX::unsignedDecode<77>(GFWX::Bits&)
Line
Count
Source
204
3.26k
  {
205
3.26k
    uint32_t x = stream.getZeros(12);
206
3.26k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
3.26k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
3.26k
  }
unsigned int GFWX::unsignedDecode<81>(GFWX::Bits&)
Line
Count
Source
204
2.98k
  {
205
2.98k
    uint32_t x = stream.getZeros(12);
206
2.98k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
2.98k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.98k
  }
unsigned int GFWX::unsignedDecode<85>(GFWX::Bits&)
Line
Count
Source
204
2.92k
  {
205
2.92k
    uint32_t x = stream.getZeros(12);
206
2.92k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
2.92k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.92k
  }
unsigned int GFWX::unsignedDecode<89>(GFWX::Bits&)
Line
Count
Source
204
2.85k
  {
205
2.85k
    uint32_t x = stream.getZeros(12);
206
2.85k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
2.85k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.85k
  }
unsigned int GFWX::unsignedDecode<93>(GFWX::Bits&)
Line
Count
Source
204
2.32k
  {
205
2.32k
    uint32_t x = stream.getZeros(12);
206
2.32k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
2.32k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.32k
  }
unsigned int GFWX::unsignedDecode<97>(GFWX::Bits&)
Line
Count
Source
204
1.79k
  {
205
1.79k
    uint32_t x = stream.getZeros(12);
206
1.79k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.79k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.79k
  }
unsigned int GFWX::unsignedDecode<101>(GFWX::Bits&)
Line
Count
Source
204
1.59k
  {
205
1.59k
    uint32_t x = stream.getZeros(12);
206
1.59k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.59k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.59k
  }
unsigned int GFWX::unsignedDecode<105>(GFWX::Bits&)
Line
Count
Source
204
1.20k
  {
205
1.20k
    uint32_t x = stream.getZeros(12);
206
1.20k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.20k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.20k
  }
unsigned int GFWX::unsignedDecode<109>(GFWX::Bits&)
Line
Count
Source
204
1.14k
  {
205
1.14k
    uint32_t x = stream.getZeros(12);
206
1.14k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.14k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.14k
  }
unsigned int GFWX::unsignedDecode<3>(GFWX::Bits&)
Line
Count
Source
204
20.3k
  {
205
20.3k
    uint32_t x = stream.getZeros(12);
206
20.3k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
20.3k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
20.3k
  }
unsigned int GFWX::unsignedDecode<7>(GFWX::Bits&)
Line
Count
Source
204
170
  {
205
170
    uint32_t x = stream.getZeros(12);
206
170
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
170
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
170
  }
unsigned int GFWX::unsignedDecode<11>(GFWX::Bits&)
Line
Count
Source
204
128
  {
205
128
    uint32_t x = stream.getZeros(12);
206
128
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
128
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
128
  }
unsigned int GFWX::unsignedDecode<15>(GFWX::Bits&)
Line
Count
Source
204
103
  {
205
103
    uint32_t x = stream.getZeros(12);
206
103
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
103
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
103
  }
unsigned int GFWX::unsignedDecode<19>(GFWX::Bits&)
Line
Count
Source
204
95
  {
205
95
    uint32_t x = stream.getZeros(12);
206
95
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
95
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
95
  }
unsigned int GFWX::unsignedDecode<23>(GFWX::Bits&)
Line
Count
Source
204
91
  {
205
91
    uint32_t x = stream.getZeros(12);
206
91
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
91
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
91
  }
unsigned int GFWX::unsignedDecode<27>(GFWX::Bits&)
Line
Count
Source
204
88
  {
205
88
    uint32_t x = stream.getZeros(12);
206
88
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
88
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
88
  }
unsigned int GFWX::unsignedDecode<31>(GFWX::Bits&)
Line
Count
Source
204
87
  {
205
87
    uint32_t x = stream.getZeros(12);
206
87
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
87
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
87
  }
unsigned int GFWX::unsignedDecode<35>(GFWX::Bits&)
Line
Count
Source
204
87
  {
205
87
    uint32_t x = stream.getZeros(12);
206
87
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
87
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
87
  }
unsigned int GFWX::unsignedDecode<39>(GFWX::Bits&)
Line
Count
Source
204
79
  {
205
79
    uint32_t x = stream.getZeros(12);
206
79
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
79
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
79
  }
unsigned int GFWX::unsignedDecode<43>(GFWX::Bits&)
Line
Count
Source
204
79
  {
205
79
    uint32_t x = stream.getZeros(12);
206
79
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
79
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
79
  }
unsigned int GFWX::unsignedDecode<47>(GFWX::Bits&)
Line
Count
Source
204
74
  {
205
74
    uint32_t x = stream.getZeros(12);
206
74
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
74
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
74
  }
unsigned int GFWX::unsignedDecode<51>(GFWX::Bits&)
Line
Count
Source
204
72
  {
205
72
    uint32_t x = stream.getZeros(12);
206
72
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
72
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
72
  }
unsigned int GFWX::unsignedDecode<55>(GFWX::Bits&)
Line
Count
Source
204
71
  {
205
71
    uint32_t x = stream.getZeros(12);
206
71
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
71
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
71
  }
unsigned int GFWX::unsignedDecode<59>(GFWX::Bits&)
Line
Count
Source
204
70
  {
205
70
    uint32_t x = stream.getZeros(12);
206
70
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
70
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
70
  }
unsigned int GFWX::unsignedDecode<63>(GFWX::Bits&)
Line
Count
Source
204
70
  {
205
70
    uint32_t x = stream.getZeros(12);
206
70
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
70
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
70
  }
unsigned int GFWX::unsignedDecode<67>(GFWX::Bits&)
Line
Count
Source
204
62
  {
205
62
    uint32_t x = stream.getZeros(12);
206
62
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
62
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
62
  }
unsigned int GFWX::unsignedDecode<71>(GFWX::Bits&)
Line
Count
Source
204
62
  {
205
62
    uint32_t x = stream.getZeros(12);
206
62
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
62
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
62
  }
unsigned int GFWX::unsignedDecode<75>(GFWX::Bits&)
Line
Count
Source
204
57
  {
205
57
    uint32_t x = stream.getZeros(12);
206
57
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
57
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
57
  }
unsigned int GFWX::unsignedDecode<79>(GFWX::Bits&)
Line
Count
Source
204
57
  {
205
57
    uint32_t x = stream.getZeros(12);
206
57
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
57
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
57
  }
unsigned int GFWX::unsignedDecode<83>(GFWX::Bits&)
Line
Count
Source
204
55
  {
205
55
    uint32_t x = stream.getZeros(12);
206
55
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
55
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
55
  }
unsigned int GFWX::unsignedDecode<87>(GFWX::Bits&)
Line
Count
Source
204
55
  {
205
55
    uint32_t x = stream.getZeros(12);
206
55
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
55
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
55
  }
unsigned int GFWX::unsignedDecode<91>(GFWX::Bits&)
Line
Count
Source
204
55
  {
205
55
    uint32_t x = stream.getZeros(12);
206
55
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
55
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
55
  }
unsigned int GFWX::unsignedDecode<95>(GFWX::Bits&)
Line
Count
Source
204
53
  {
205
53
    uint32_t x = stream.getZeros(12);
206
53
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
53
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
53
  }
unsigned int GFWX::unsignedDecode<99>(GFWX::Bits&)
Line
Count
Source
204
53
  {
205
53
    uint32_t x = stream.getZeros(12);
206
53
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
53
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
53
  }
unsigned int GFWX::unsignedDecode<103>(GFWX::Bits&)
Line
Count
Source
204
53
  {
205
53
    uint32_t x = stream.getZeros(12);
206
53
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
53
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
53
  }
unsigned int GFWX::unsignedDecode<107>(GFWX::Bits&)
Line
Count
Source
204
53
  {
205
53
    uint32_t x = stream.getZeros(12);
206
53
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
53
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
53
  }
unsigned int GFWX::unsignedDecode<111>(GFWX::Bits&)
Line
Count
Source
204
53
  {
205
53
    uint32_t x = stream.getZeros(12);
206
53
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
53
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
53
  }
unsigned int GFWX::unsignedDecode<4>(GFWX::Bits&)
Line
Count
Source
204
61.3k
  {
205
61.3k
    uint32_t x = stream.getZeros(12);
206
61.3k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
61.3k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
61.3k
  }
unsigned int GFWX::unsignedDecode<8>(GFWX::Bits&)
Line
Count
Source
204
1.82k
  {
205
1.82k
    uint32_t x = stream.getZeros(12);
206
1.82k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.82k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.82k
  }
unsigned int GFWX::unsignedDecode<12>(GFWX::Bits&)
Line
Count
Source
204
1.40k
  {
205
1.40k
    uint32_t x = stream.getZeros(12);
206
1.40k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.40k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.40k
  }
unsigned int GFWX::unsignedDecode<16>(GFWX::Bits&)
Line
Count
Source
204
1.24k
  {
205
1.24k
    uint32_t x = stream.getZeros(12);
206
1.24k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.24k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.24k
  }
unsigned int GFWX::unsignedDecode<20>(GFWX::Bits&)
Line
Count
Source
204
1.19k
  {
205
1.19k
    uint32_t x = stream.getZeros(12);
206
1.19k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.19k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.19k
  }
unsigned int GFWX::unsignedDecode<24>(GFWX::Bits&)
Line
Count
Source
204
1.15k
  {
205
1.15k
    uint32_t x = stream.getZeros(12);
206
1.15k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.15k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.15k
  }
unsigned int GFWX::unsignedDecode<28>(GFWX::Bits&)
Line
Count
Source
204
1.12k
  {
205
1.12k
    uint32_t x = stream.getZeros(12);
206
1.12k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.12k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.12k
  }
unsigned int GFWX::unsignedDecode<32>(GFWX::Bits&)
Line
Count
Source
204
1.10k
  {
205
1.10k
    uint32_t x = stream.getZeros(12);
206
1.10k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.10k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.10k
  }
unsigned int GFWX::unsignedDecode<36>(GFWX::Bits&)
Line
Count
Source
204
1.10k
  {
205
1.10k
    uint32_t x = stream.getZeros(12);
206
1.10k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.10k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.10k
  }
unsigned int GFWX::unsignedDecode<40>(GFWX::Bits&)
Line
Count
Source
204
1.08k
  {
205
1.08k
    uint32_t x = stream.getZeros(12);
206
1.08k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.08k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.08k
  }
unsigned int GFWX::unsignedDecode<44>(GFWX::Bits&)
Line
Count
Source
204
1.04k
  {
205
1.04k
    uint32_t x = stream.getZeros(12);
206
1.04k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.04k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.04k
  }
unsigned int GFWX::unsignedDecode<48>(GFWX::Bits&)
Line
Count
Source
204
1.03k
  {
205
1.03k
    uint32_t x = stream.getZeros(12);
206
1.03k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.03k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.03k
  }
unsigned int GFWX::unsignedDecode<52>(GFWX::Bits&)
Line
Count
Source
204
1.00k
  {
205
1.00k
    uint32_t x = stream.getZeros(12);
206
1.00k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
1.00k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.00k
  }
unsigned int GFWX::unsignedDecode<56>(GFWX::Bits&)
Line
Count
Source
204
992
  {
205
992
    uint32_t x = stream.getZeros(12);
206
992
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
992
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
992
  }
unsigned int GFWX::unsignedDecode<60>(GFWX::Bits&)
Line
Count
Source
204
979
  {
205
979
    uint32_t x = stream.getZeros(12);
206
979
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
979
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
979
  }
unsigned int GFWX::unsignedDecode<64>(GFWX::Bits&)
Line
Count
Source
204
976
  {
205
976
    uint32_t x = stream.getZeros(12);
206
976
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
976
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
976
  }
unsigned int GFWX::unsignedDecode<68>(GFWX::Bits&)
Line
Count
Source
204
960
  {
205
960
    uint32_t x = stream.getZeros(12);
206
960
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
960
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
960
  }
unsigned int GFWX::unsignedDecode<72>(GFWX::Bits&)
Line
Count
Source
204
848
  {
205
848
    uint32_t x = stream.getZeros(12);
206
848
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
848
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
848
  }
unsigned int GFWX::unsignedDecode<76>(GFWX::Bits&)
Line
Count
Source
204
842
  {
205
842
    uint32_t x = stream.getZeros(12);
206
842
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
842
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
842
  }
unsigned int GFWX::unsignedDecode<80>(GFWX::Bits&)
Line
Count
Source
204
837
  {
205
837
    uint32_t x = stream.getZeros(12);
206
837
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
837
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
837
  }
unsigned int GFWX::unsignedDecode<84>(GFWX::Bits&)
Line
Count
Source
204
822
  {
205
822
    uint32_t x = stream.getZeros(12);
206
822
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
822
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
822
  }
unsigned int GFWX::unsignedDecode<88>(GFWX::Bits&)
Line
Count
Source
204
807
  {
205
807
    uint32_t x = stream.getZeros(12);
206
807
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
807
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
807
  }
unsigned int GFWX::unsignedDecode<92>(GFWX::Bits&)
Line
Count
Source
204
801
  {
205
801
    uint32_t x = stream.getZeros(12);
206
801
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
801
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
801
  }
unsigned int GFWX::unsignedDecode<96>(GFWX::Bits&)
Line
Count
Source
204
783
  {
205
783
    uint32_t x = stream.getZeros(12);
206
783
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
783
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
783
  }
unsigned int GFWX::unsignedDecode<100>(GFWX::Bits&)
Line
Count
Source
204
781
  {
205
781
    uint32_t x = stream.getZeros(12);
206
781
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
781
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
781
  }
unsigned int GFWX::unsignedDecode<104>(GFWX::Bits&)
Line
Count
Source
204
753
  {
205
753
    uint32_t x = stream.getZeros(12);
206
753
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
753
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
753
  }
unsigned int GFWX::unsignedDecode<108>(GFWX::Bits&)
Line
Count
Source
204
713
  {
205
713
    uint32_t x = stream.getZeros(12);
206
713
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
713
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
713
  }
unsigned int GFWX::unsignedDecode<0>(GFWX::Bits&)
Line
Count
Source
204
54.0k
  {
205
54.0k
    uint32_t x = stream.getZeros(12);
206
54.0k
    int const p = pot < 24 ? pot : 24;  // actual pot. The max 108 below is to prevent unlimited recursion in malformed files, yet admit 2^32 - 1.
207
54.0k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
54.0k
  }
209
210
  template<int pot> void interleavedCode(int x, Bits & stream)
211
12.2M
  {
212
12.2M
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
12.2M
  }
void GFWX::interleavedCode<1>(int, GFWX::Bits&)
Line
Count
Source
211
7.84M
  {
212
7.84M
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
7.84M
  }
void GFWX::interleavedCode<0>(int, GFWX::Bits&)
Line
Count
Source
211
2.92M
  {
212
2.92M
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
2.92M
  }
void GFWX::interleavedCode<2>(int, GFWX::Bits&)
Line
Count
Source
211
364k
  {
212
364k
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
364k
  }
void GFWX::interleavedCode<3>(int, GFWX::Bits&)
Line
Count
Source
211
436k
  {
212
436k
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
436k
  }
void GFWX::interleavedCode<4>(int, GFWX::Bits&)
Line
Count
Source
211
698k
  {
212
698k
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
698k
  }
214
215
  template<int pot> int interleavedDecode(Bits & stream)
216
143k
  {
217
143k
    int const x = unsignedDecode<pot>(stream);
218
143k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
143k
  }
int GFWX::interleavedDecode<1>(GFWX::Bits&)
Line
Count
Source
216
60.4k
  {
217
60.4k
    int const x = unsignedDecode<pot>(stream);
218
60.4k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
60.4k
  }
int GFWX::interleavedDecode<0>(GFWX::Bits&)
Line
Count
Source
216
54.0k
  {
217
54.0k
    int const x = unsignedDecode<pot>(stream);
218
54.0k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
54.0k
  }
int GFWX::interleavedDecode<2>(GFWX::Bits&)
Line
Count
Source
216
12.9k
  {
217
12.9k
    int const x = unsignedDecode<pot>(stream);
218
12.9k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
12.9k
  }
int GFWX::interleavedDecode<3>(GFWX::Bits&)
Line
Count
Source
216
10.9k
  {
217
10.9k
    int const x = unsignedDecode<pot>(stream);
218
10.9k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
10.9k
  }
int GFWX::interleavedDecode<4>(GFWX::Bits&)
Line
Count
Source
216
4.77k
  {
217
4.77k
    int const x = unsignedDecode<pot>(stream);
218
4.77k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
4.77k
  }
220
221
  template<int pot> void signedCode(int x, Bits & stream)
222
13.7M
  {
223
13.7M
    unsignedCode<pot>(abs(x), stream);
224
13.7M
    if (x)
225
11.9M
      stream.putBits(x > 0 ? 1 : 0, 1);
226
13.7M
  }
void GFWX::signedCode<2>(int, GFWX::Bits&)
Line
Count
Source
222
333k
  {
223
333k
    unsignedCode<pot>(abs(x), stream);
224
333k
    if (x)
225
233k
      stream.putBits(x > 0 ? 1 : 0, 1);
226
333k
  }
void GFWX::signedCode<4>(int, GFWX::Bits&)
Line
Count
Source
222
12.4M
  {
223
12.4M
    unsignedCode<pot>(abs(x), stream);
224
12.4M
    if (x)
225
11.1M
      stream.putBits(x > 0 ? 1 : 0, 1);
226
12.4M
  }
void GFWX::signedCode<1>(int, GFWX::Bits&)
Line
Count
Source
222
302k
  {
223
302k
    unsignedCode<pot>(abs(x), stream);
224
302k
    if (x)
225
158k
      stream.putBits(x > 0 ? 1 : 0, 1);
226
302k
  }
void GFWX::signedCode<3>(int, GFWX::Bits&)
Line
Count
Source
222
646k
  {
223
646k
    unsignedCode<pot>(abs(x), stream);
224
646k
    if (x)
225
466k
      stream.putBits(x > 0 ? 1 : 0, 1);
226
646k
  }
227
228
  template<int pot> int signedDecode(Bits & stream)
229
5.04M
  {
230
5.04M
    int x = unsignedDecode<pot>(stream);
231
5.04M
    return x ? stream.getBits(1) ? x : -x : 0;
232
5.04M
  }
int GFWX::signedDecode<2>(GFWX::Bits&)
Line
Count
Source
229
5.01M
  {
230
5.01M
    int x = unsignedDecode<pot>(stream);
231
5.01M
    return x ? stream.getBits(1) ? x : -x : 0;
232
5.01M
  }
int GFWX::signedDecode<4>(GFWX::Bits&)
Line
Count
Source
229
13.5k
  {
230
13.5k
    int x = unsignedDecode<pot>(stream);
231
13.5k
    return x ? stream.getBits(1) ? x : -x : 0;
232
13.5k
  }
int GFWX::signedDecode<1>(GFWX::Bits&)
Line
Count
Source
229
4.26k
  {
230
4.26k
    int x = unsignedDecode<pot>(stream);
231
4.26k
    return x ? stream.getBits(1) ? x : -x : 0;
232
4.26k
  }
int GFWX::signedDecode<3>(GFWX::Bits&)
Line
Count
Source
229
7.98k
  {
230
7.98k
    int x = unsignedDecode<pot>(stream);
231
7.98k
    return x ? stream.getBits(1) ? x : -x : 0;
232
7.98k
  }
233
234
  template<typename T> T median(T a, T b, T c)
235
146M
  {
236
146M
    return a < b ? c > b ? b : c < a ? a : c : c > a ? a : c < b ? b : c;
237
146M
  }
238
239
  template<typename T> T roundFraction(T num, T denom)
240
146M
  {
241
146M
    return num < 0 ? (num - denom / 2) / denom : (num + denom / 2) / denom;
242
146M
  }
243
244
  template<typename T> T cubic(T c0, T c1, T c2, T c3)
245
146M
  {
246
146M
    return median(T(roundFraction((-c0 + 9 * (c1 + c2) - c3), 16)), c1, c2);
247
146M
  }
248
249
  template<typename T> void lift(Image<T> & image, int x0, int y0, int x1, int y1, int step, int filter)
250
21.4k
  {
251
21.4k
    int const sizex = x1 - x0;
252
21.4k
    int const sizey = y1 - y0;
253
127k
    while (step < sizex || step < sizey)
254
106k
    {
255
106k
      if (step < sizex)  // horizontal lifting
256
51.2k
      {
257
51.2k
        OMP_PARALLEL_FOR(ThreadIterations)
258
20.8M
        for (int y = 0; y < sizey; y += step)
259
20.8M
        {
260
20.8M
          int x;
261
20.8M
          T * base = &image[y0 + y][x0], * base1 = base - step, * base2 = base + step, * base3 = base + step * 3;
262
20.8M
          if (filter == FilterCubic)
263
11.1M
          {
264
11.1M
            T c0 = *base, c1 = *base, c2 = step * 2 < sizex ? base[step * 2] : *base, c3;
265
26.9M
            for (x = step; x < sizex - step * 3; x += step * 2, c0 = c1, c1 = c2, c2 = c3)
266
15.8M
              base[x] -= cubic(c0, c1, c2, c3 = base3[x]);
267
25.9M
            for (; x < sizex; x += step * 2, c0 = c1, c1 = c2)
268
14.8M
              base[x] -= cubic(c0, c1, c2, c2);
269
11.1M
            T g0 = base[step], g1 = base[step], g2 = step * 3 < sizex ? base[step * 3] : base[step], g3;
270
26.1M
            for (x = step * 2; x < sizex - step * 3; x += step * 2, g0 = g1, g1 = g2, g2 = g3)
271
14.9M
              base[x] += cubic(g0, g1, g2, g3 = base3[x]) / 2;
272
17.4M
            for (; x < sizex; x += step * 2, g0 = g1, g1 = g2)
273
6.23M
              base[x] += cubic(g0, g1, g2, g2) / 2;
274
11.1M
          }
275
9.66M
          else
276
9.66M
          {
277
37.8M
            for (x = step; x < sizex - step; x += step * 2)
278
28.1M
              base[x] -= (base1[x] + base2[x]) / 2;
279
9.66M
            if (x < sizex)
280
8.31M
              base[x] -= base1[x];
281
36.4M
            for (x = step * 2; x < sizex - step; x += step * 2)
282
26.8M
              base[x] += (base1[x] + base2[x]) / 4;
283
9.66M
            if (x < sizex)
284
1.35M
              base[x] += base1[x] / 2;
285
9.66M
          }
286
20.8M
        }
287
51.2k
      }
288
106k
      if (step < sizey)  // vertical lifting
289
74.8k
      {
290
74.8k
        OMP_PARALLEL_FOR(ThreadIterations)
291
66.5M
        for (int y = step; y < sizey; y += step * 2)
292
66.5M
        {
293
66.5M
          T * const base = &image[y0 + y][x0];
294
66.5M
          T const * const c1base = &image[y0 + y - step][x0], * const c2base = y + step < sizey ? &image[y0 + y + step][x0] : c1base;
295
66.5M
          if (filter == FilterCubic)
296
36.7M
          {
297
36.7M
            T const * const c0base = y - step * 3 >= 0 ? &image[y0 + y - step * 3][x0] : c1base;
298
36.7M
            T const * const c3base = y + step * 3 < sizey ? &image[y0 + y + step * 3][x0] : c2base;
299
83.7M
            for (int x = 0; x < sizex; x += step)
300
47.0M
              base[x] -= cubic(c0base[x], c1base[x], c2base[x], c3base[x]);
301
36.7M
          }
302
70.8M
          else for (int x = 0; x < sizex; x += step)
303
41.0M
            base[x] -= (c1base[x] + c2base[x]) / 2;
304
66.5M
        }
305
74.8k
        OMP_PARALLEL_FOR(ThreadIterations)
306
66.5M
        for (int y = step * 2; y < sizey; y += step * 2)
307
66.4M
        {
308
66.4M
          T * const base = &image[y0 + y][x0];
309
66.4M
          T const * const g1base = &image[y0 + y - step][x0], * const g2base = y + step < sizey ? &image[y0 + y + step][x0] : g1base;
310
66.4M
          if (filter == FilterCubic)
311
36.7M
          {
312
36.7M
            T const * const g0base = y - step * 3 >= 0 ? &image[y0 + y - step * 3][x0] : g1base;
313
36.7M
            T const * const g3base = y + step * 3 < sizey ? &image[y0 + y + step * 3][x0] : g2base;
314
83.0M
            for (int x = 0; x < sizex; x += step)
315
46.3M
              base[x] += cubic(g0base[x], g1base[x], g2base[x], g3base[x]) / 2;
316
36.7M
          }
317
69.1M
          else for (int x = 0; x < sizex; x += step)
318
39.3M
            base[x] += (g1base[x] + g2base[x]) / 4;
319
66.4M
        }
320
74.8k
      }
321
106k
      step *= 2;
322
106k
    }
323
21.4k
  }
324
325
  template<typename T> void unlift(Image<T> & image, int x0, int y0, int x1, int y1, int minStep, int filter)
326
542
  {
327
542
    int const sizex = x1 - x0;
328
542
    int const sizey = y1 - y0;
329
542
    int step = minStep;
330
4.38k
    while (step * 2 < sizex || step * 2 < sizey)
331
3.84k
      step *= 2;
332
4.92k
    while (step >= minStep)
333
4.38k
    {
334
4.38k
      if (step < sizey)  // vertical unlifting
335
1.12k
      {
336
1.12k
        OMP_PARALLEL_FOR(ThreadIterations)
337
15.1k
        for (int y = step * 2; y < sizey; y += step * 2)
338
14.0k
        {
339
14.0k
          T * const base = &image[y0 + y][x0];
340
14.0k
          T const * const g1base = &image[y0 + y - step][x0], * const g2base = y + step < sizey ? &image[y0 + y + step][x0] : g1base;
341
14.0k
          if (filter == FilterCubic)
342
5.62k
          {
343
5.62k
            T const * const g0base = y - step * 3 >= 0 ? &image[y0 + y - step * 3][x0] : g1base;
344
5.62k
            T const * const g3base = y + step * 3 < sizey ? &image[y0 + y + step * 3][x0] : g2base;
345
425k
            for (int x = 0; x < sizex; x += step)
346
419k
              base[x] -= cubic(g0base[x], g1base[x], g2base[x], g3base[x]) / 2;
347
5.62k
          }
348
1.39M
          else for (int x = 0; x < sizex; x += step)
349
1.39M
            base[x] -= (g1base[x] + g2base[x]) / 4;
350
14.0k
        }
351
1.12k
        OMP_PARALLEL_FOR(ThreadIterations)
352
15.7k
        for (int y = step; y < sizey; y += step * 2)
353
14.6k
        {
354
14.6k
          T * const base = &image[y0 + y][x0];
355
14.6k
          T const * const c1base = &image[y0 + y - step][x0], * const c2base = y + step < sizey ? &image[y0 + y + step][x0] : c1base;
356
14.6k
          if (filter == FilterCubic)
357
5.73k
          {
358
5.73k
            T const * const c0base = y - step * 3 >= 0 ? &image[y0 + y - step * 3][x0] : c1base;
359
5.73k
            T const * const c3base = y + step * 3 < sizey ? &image[y0 + y + step * 3][x0] : c2base;
360
427k
            for (int x = 0; x < sizex; x += step)
361
421k
              base[x] += cubic(c0base[x], c1base[x], c2base[x], c3base[x]);
362
5.73k
          }
363
1.45M
          else for (int x = 0; x < sizex; x += step)
364
1.45M
            base[x] += (c1base[x] + c2base[x]) / 2;
365
14.6k
        }
366
1.12k
      }
367
4.38k
      if (step < sizex)  // horizontal unlifting
368
4.35k
      {
369
4.35k
        OMP_PARALLEL_FOR(ThreadIterations)
370
36.6k
        for (int y = 0; y < sizey; y += step)
371
32.3k
        {
372
32.3k
          int x;
373
32.3k
          T * base = &image[y0 + y][x0], * base1 = base - step, * base2 = base + step, * base3 = base + step * 3;
374
32.3k
          if (filter == FilterCubic)
375
11.4k
          {
376
11.4k
            T g0 = base[step], g1 = base[step], g2 = step * 3 < sizex ? base[step * 3] : base[step], g3;
377
409k
            for (x = step * 2; x < sizex - step * 3; x += step * 2, g0 = g1, g1 = g2, g2 = g3)
378
397k
              base[x] -= cubic(g0, g1, g2, g3 = base3[x]) / 2;
379
25.9k
            for (; x < sizex; x += step * 2, g0 = g1, g1 = g2)
380
14.5k
              base[x] -= cubic(g0, g1, g2, g2) / 2;
381
11.4k
            T c0 = *base, c1 = *base, c2 = step * 2 < sizex ? base[step * 2] : *base, c3;
382
412k
            for (x = step; x < sizex - step * 3; x += step * 2, c0 = c1, c1 = c2, c2 = c3)
383
400k
              base[x] += cubic(c0, c1, c2, c3 = base3[x]);
384
30.9k
            for (; x < sizex; x += step * 2, c0 = c1, c1 = c2)
385
19.5k
              base[x] += cubic(c0, c1, c2, c2);
386
11.4k
          }
387
20.9k
          else
388
20.9k
          {
389
1.56M
            for (x = step * 2; x < sizex - step; x += step * 2)
390
1.54M
              base[x] -= (base1[x] + base2[x]) / 4;
391
20.9k
            if (x < sizex)
392
15.2k
              base[x] -= base1[x] / 2;
393
1.58M
            for (x = step; x < sizex - step; x += step * 2)
394
1.55M
              base[x] += (base1[x] + base2[x]) / 2;
395
20.9k
            if (x < sizex)
396
5.63k
              base[x] += base1[x];
397
20.9k
          }
398
32.3k
        }
399
4.35k
      }
400
4.38k
      step /= 2;
401
4.38k
    }
402
542
  }
403
404
  template<typename T, bool dequantize> void quantize(Image<T> & image, int x0, int y0, int x1, int y1, int step, int quality, int minQ, int maxQ)
405
21.9k
  {
406
21.9k
    typedef typename std::conditional<sizeof(T) < 4, int32_t, int64_t>::type aux;
407
21.9k
    int const sizex = x1 - x0;
408
21.9k
    int const sizey = y1 - y0;
409
21.9k
    int skip = step;
410
38.4k
    while (skip < sizex && skip < sizey)
411
17.7k
    {
412
17.7k
      int const q = std::max(std::max(1, minQ), quality);
413
17.7k
      if (q >= maxQ) break;
414
16.4k
      OMP_PARALLEL_FOR(ThreadIterations)
415
19.9M
      for (int y = 0; y < sizey; y += skip)
416
19.9M
      {
417
19.9M
        T * base = &image[y0 + y][x0];
418
19.9M
        int const xStep = (y & skip) ? skip : skip * 2;
419
87.6M
        for (int x = xStep - skip; x < sizex; x += xStep)  // [NOTE] arranged so that (x | y) & skip == 1
420
67.6M
          base[x] = dequantize ? (aux(base[x]) * maxQ + (base[x] < 0 ? -maxQ / 2 : base[x] > 0 ? maxQ / 2 : 0)) / q : aux(base[x]) * q / maxQ;
421
19.9M
      }
422
16.4k
      skip *= 2;
423
16.4k
      quality = std::min(maxQ, quality * 2);  // [MAGIC] This approximates the JPEG 2000 baseline quantizer
424
16.4k
    }
425
21.9k
  }
void GFWX::quantize<short, false>(GFWX::Image<short>&, int, int, int, int, int, int, int, int)
Line
Count
Source
405
21.4k
  {
406
21.4k
    typedef typename std::conditional<sizeof(T) < 4, int32_t, int64_t>::type aux;
407
21.4k
    int const sizex = x1 - x0;
408
21.4k
    int const sizey = y1 - y0;
409
21.4k
    int skip = step;
410
37.1k
    while (skip < sizex && skip < sizey)
411
16.7k
    {
412
16.7k
      int const q = std::max(std::max(1, minQ), quality);
413
16.7k
      if (q >= maxQ) break;
414
15.7k
      OMP_PARALLEL_FOR(ThreadIterations)
415
19.9M
      for (int y = 0; y < sizey; y += skip)
416
19.9M
      {
417
19.9M
        T * base = &image[y0 + y][x0];
418
19.9M
        int const xStep = (y & skip) ? skip : skip * 2;
419
84.7M
        for (int x = xStep - skip; x < sizex; x += xStep)  // [NOTE] arranged so that (x | y) & skip == 1
420
64.8M
          base[x] = dequantize ? (aux(base[x]) * maxQ + (base[x] < 0 ? -maxQ / 2 : base[x] > 0 ? maxQ / 2 : 0)) / q : aux(base[x]) * q / maxQ;
421
19.9M
      }
422
15.7k
      skip *= 2;
423
15.7k
      quality = std::min(maxQ, quality * 2);  // [MAGIC] This approximates the JPEG 2000 baseline quantizer
424
15.7k
    }
425
21.4k
  }
void GFWX::quantize<short, true>(GFWX::Image<short>&, int, int, int, int, int, int, int, int)
Line
Count
Source
405
542
  {
406
542
    typedef typename std::conditional<sizeof(T) < 4, int32_t, int64_t>::type aux;
407
542
    int const sizex = x1 - x0;
408
542
    int const sizey = y1 - y0;
409
542
    int skip = step;
410
1.30k
    while (skip < sizex && skip < sizey)
411
917
    {
412
917
      int const q = std::max(std::max(1, minQ), quality);
413
917
      if (q >= maxQ) break;
414
761
      OMP_PARALLEL_FOR(ThreadIterations)
415
28.9k
      for (int y = 0; y < sizey; y += skip)
416
28.2k
      {
417
28.2k
        T * base = &image[y0 + y][x0];
418
28.2k
        int const xStep = (y & skip) ? skip : skip * 2;
419
2.83M
        for (int x = xStep - skip; x < sizex; x += xStep)  // [NOTE] arranged so that (x | y) & skip == 1
420
2.80M
          base[x] = dequantize ? (aux(base[x]) * maxQ + (base[x] < 0 ? -maxQ / 2 : base[x] > 0 ? maxQ / 2 : 0)) / q : aux(base[x]) * q / maxQ;
421
28.2k
      }
422
761
      skip *= 2;
423
761
      quality = std::min(maxQ, quality * 2);  // [MAGIC] This approximates the JPEG 2000 baseline quantizer
424
761
    }
425
542
  }
426
427
  template<typename T> T square(T t)
428
57.9M
  {
429
57.9M
    return t * t;
430
57.9M
  }
431
432
  inline void addContext(int x, int w, uint32_t & sum, uint32_t & sum2, uint32_t & count)
433
34.7M
  {
434
34.7M
    sum += uint32_t(x = abs(x)) * w;
435
34.7M
    sum2 += square(std::min(uint32_t(x), 4096u)) * w; // [MAGIC] avoid overflow in last line of getContext
436
34.7M
    count += w;
437
34.7M
  }
438
439
  template<typename T> std::pair<uint32_t, uint32_t> getContext(Image<T> & image, int x0, int y0, int x1, int y1, int x, int y, int skip)
440
14.6M
  {
441
14.6M
    int px = x0 + (x & ~(skip * 2)) + (x & skip);
442
14.6M
    if (px >= x1)
443
1.24M
      px -= skip * 2;
444
14.6M
    int py = y0 + (y & ~(skip * 2)) + (y & skip);
445
14.6M
    if (py >= y1)
446
1.54M
      py -= skip * 2;
447
14.6M
    uint32_t count = 0, sum = 0, sum2 = 0;
448
14.6M
    addContext(abs(image[py][px]), 2, sum, sum2, count);  // ancestor
449
14.6M
    if ((y & skip) && (x | skip) < x1 - x0)
450
4.13M
    {
451
4.13M
      addContext(image[y0 + y - skip][x0 + (x | skip)], 2, sum, sum2, count); // upper sibling
452
4.13M
      if (x & skip)
453
2.06M
        addContext(image[y0 + y][x0 + x - skip], 2, sum, sum2, count); // left sibling
454
4.13M
    }
455
14.6M
    if (y >= skip * 2 && x >= skip * 2)  // neighbors
456
2.16M
    {
457
2.16M
      addContext(image[y0 + y - skip * 2][x0 + x], 4, sum, sum2, count);
458
2.16M
      addContext(image[y0 + y][x0 + x - skip * 2], 4, sum, sum2, count);
459
2.16M
      addContext(image[y0 + y - skip * 2][x0 + x - skip * 2], 2, sum, sum2, count);
460
2.16M
      if (x + skip * 2 < x1 - x0)
461
1.93M
        addContext(image[y0 + y - skip * 2][x0 + x + skip * 2], 2, sum, sum2, count);
462
2.16M
      if (y >= skip * 4 && x >= skip * 4)
463
1.42M
      {
464
1.42M
        addContext(image[y0 + y - skip * 4][x0 + x], 2, sum, sum2, count);
465
1.42M
        addContext(image[y0 + y][x0 + x - skip * 4], 2, sum, sum2, count);
466
1.42M
        addContext(image[y0 + y - skip * 4][x0 + x - skip * 4], 1, sum, sum2, count);
467
1.42M
        if (x + skip * 4 < x1 - x0)
468
1.23M
          addContext(image[y0 + y - skip * 4][x0 + x + skip * 4], 1, sum, sum2, count);
469
1.42M
      }
470
2.16M
    }
471
14.6M
    return std::make_pair((sum * 16u + count / 2u) / count, (sum2 * 16u + count / 2u) / count); // set sums relative to 16 count
472
14.6M
  }
473
474
  template<typename T> void encode(Image<T> & image, Bits & stream, int x0, int y0, int x1, int y1, int step, int scheme, int q, bool hasDC, bool isChroma)
475
8.01M
  {
476
8.01M
    int const sizex = x1 - x0;
477
8.01M
    int const sizey = y1 - y0;
478
8.01M
    if (hasDC && sizex > 0 && sizey > 0)
479
14.8k
      signedCode<4>(image[y0][x0], stream);
480
8.01M
    std::pair<uint32_t, uint32_t> context(0, 0);
481
8.01M
    int run = 0, runCoder = (scheme == EncoderTurbo ? (!q || (step < 2048 && q * step < 2048)) ? 1 : 0 : 0);  // avoid overflow checking q * step < 2048
482
90.4M
    for (int y = 0; y < sizey; y += step)
483
82.4M
    {
484
82.4M
      T * base = &image[y0 + y][x0];
485
82.4M
      int const xStep = (y & step) ? step : step * 2;
486
172M
      for (int x = xStep - step; x < sizex; x += xStep)  // [NOTE] arranged so that (x | y) & step == 1
487
89.8M
      {
488
89.8M
        T s = base[x];
489
89.8M
        if (runCoder && !s)  // run
490
63.8M
          ++ run;
491
26.0M
        else
492
26.0M
        {
493
26.0M
          if (scheme == EncoderTurbo)
494
7.24M
          {
495
7.24M
            if (runCoder)  // break the run
496
4.17M
            {
497
4.17M
              unsignedCode<1>(run, stream);
498
4.17M
              run = 0;
499
4.17M
              interleavedCode<1>(s < 0 ? s + 1 : s, stream);  // s can't be zero, so shift negatives by 1
500
4.17M
            }
501
3.06M
            else
502
3.06M
              interleavedCode<1>(s, stream);
503
7.24M
            continue;
504
7.24M
          }
505
18.7M
          if (runCoder)  // break the run
506
394k
          {
507
394k
            runCoder == 1 ? unsignedCode<1>(run, stream) : runCoder == 2 ? unsignedCode<2>(run, stream)
508
315k
              : runCoder == 3 ? unsignedCode<3>(run, stream) : unsignedCode<4>(run, stream);
509
394k
            run = 0;
510
394k
            if (s < 0)
511
199k
              ++ s; // s can't be zero, so shift negatives by 1
512
394k
          }
513
18.7M
          if (scheme == EncoderContextual)
514
14.4M
            context = getContext(image, x0, y0, x1, y1, x, y, step);
515
18.7M
          uint32_t const sumSq = square(context.first);
516
18.7M
          if (sumSq < 2u * context.second + (isChroma ? 250u : 100u))
517
2.92M
            interleavedCode<0>(s, stream);
518
15.8M
          else if (sumSq < 2u * context.second + 950u)
519
601k
            interleavedCode<1>(s, stream);
520
15.2M
          else if (sumSq < 3u * context.second + 3000u)
521
667k
          {
522
667k
            if (sumSq < 5u * context.second + 400u)
523
302k
              signedCode<1>(s, stream);
524
364k
            else
525
364k
              interleavedCode<2>(s, stream);
526
667k
          }
527
14.5M
          else if (sumSq < 3u * context.second + 12000u)
528
751k
          {
529
751k
            if (sumSq < 5u * context.second + 3000u)
530
314k
              signedCode<2>(s, stream);
531
436k
            else
532
436k
              interleavedCode<3>(s, stream);
533
751k
          }
534
13.8M
          else if (sumSq < 4u * context.second + 44000u)
535
1.34M
          {
536
1.34M
            if (sumSq < 6u * context.second + 12000u)
537
646k
              signedCode<3>(s, stream);
538
698k
            else
539
698k
              interleavedCode<4>(s, stream);
540
1.34M
          }
541
12.4M
          else
542
12.4M
            signedCode<4>(s, stream);
543
18.7M
          if (scheme == EncoderFast)  // use decaying first and second moment
544
4.30M
          {
545
4.30M
            uint32_t const t = abs(s);
546
4.30M
            context = std::make_pair(((context.first * 15u + 7u) >> 4) + t, ((context.second * 15u + 7u) >> 4) + square(std::min(t, 4096u)));
547
4.30M
            if (!s == !runCoder)
548
1.86M
              runCoder = context.first < 1 ? 4 : context.first < 2 ? 3 : context.first < 4 ? 2 : context.first < 8 ? 1 : 0;
549
4.30M
          }
550
14.4M
          else if (!s == !runCoder)
551
2.79M
            runCoder = q == 1024 ? context.first < 2u ? 1 : 0 : (context.first < 4u && context.second < 2u) ? 4 : (context.first < 8u
552
2.04M
            && context.second < 4u) ? 3 : (2u * sumSq < 3u * context.second + 48u) ? 2 : (2u * sumSq < 5u * context.second + 32u) ? 1 : 0;
553
18.7M
        }
554
89.8M
      }
555
82.4M
    }
556
8.01M
    if (run)  // flush run
557
1.62M
      runCoder == 1 ? unsignedCode<1>(run, stream) : runCoder == 2 ? unsignedCode<2>(run, stream)
558
323k
        : runCoder == 3 ? unsignedCode<3>(run, stream) : unsignedCode<4>(run, stream);
559
8.01M
  }
560
561
  template<typename T> void decode(Image<T> & image, Bits & stream, int x0, int y0, int x1, int y1, int step, int scheme, int q, bool hasDC, bool isChroma)
562
48
  {
563
48
    int const sizex = x1 - x0;
564
48
    int const sizey = y1 - y0;
565
48
    if (hasDC && sizex > 0 && sizey > 0)
566
5
      image[y0][x0] = signedDecode<4>(stream);
567
48
    std::pair<uint32_t, uint32_t> context(0, 0);
568
48
    int run = -1, runCoder = (scheme == EncoderTurbo ? (!q || (step < 2048 && q * step < 2048)) ? 1 : 0 : 0);  // avoid overflow checking q * step < 2048
569
1.01k
    for (int y = 0; y < sizey; y += step)
570
963
    {
571
963
      T * base = &image[y0 + y][x0];
572
963
      int const xStep = (y & step) ? step : step * 2;
573
516k
      for (int x = xStep - step; x < sizex; x += xStep)  // [NOTE] arranged so that (x | y) & step == 1
574
515k
      {
575
515k
        T s = 0;
576
515k
        if (runCoder && run == -1)
577
50.2k
          run = runCoder == 1 ? unsignedDecode<1>(stream) : runCoder == 2 ? unsignedDecode<2>(stream)
578
48.6k
            : runCoder == 3 ? unsignedDecode<3>(stream) : unsignedDecode<4>(stream);
579
515k
        if (run > 0)
580
340k
          -- run;  // consume a zero
581
175k
        else
582
175k
        {
583
175k
          if (scheme == EncoderTurbo)
584
32.7k
            s = interleavedDecode<1>(stream);
585
142k
          else
586
142k
          {
587
142k
            if (scheme == EncoderContextual)
588
142k
              context = getContext(image, x0, y0, x1, y1, x, y, step);
589
142k
            uint32_t const sumSq = square(context.first);
590
142k
            if (sumSq < 2u * context.second + (isChroma ? 250u : 100u))
591
54.0k
              s = interleavedDecode<0>(stream);
592
88.4k
            else if (sumSq < 2u * context.second + 950u)
593
27.6k
              s = interleavedDecode<1>(stream);
594
60.7k
            else if (sumSq < 3u * context.second + 3000u)
595
17.1k
            {
596
17.1k
              if (sumSq < 5u * context.second + 400u)
597
4.26k
                s = signedDecode<1>(stream);
598
12.9k
              else
599
12.9k
                s = interleavedDecode<2>(stream);
600
17.1k
            }
601
43.5k
            else if (sumSq < 3u * context.second + 12000u)
602
17.2k
            {
603
17.2k
              if (sumSq < 5u * context.second + 3000u)
604
6.26k
                s = signedDecode<2>(stream);
605
10.9k
              else
606
10.9k
                s = interleavedDecode<3>(stream);
607
17.2k
            }
608
26.3k
            else if (sumSq < 4u * context.second + 44000u)
609
12.7k
            {
610
12.7k
              if (sumSq < 6u * context.second + 12000u)
611
7.98k
                s = signedDecode<3>(stream);
612
4.77k
              else
613
4.77k
                s = interleavedDecode<4>(stream);
614
12.7k
            }
615
13.5k
            else
616
13.5k
              s = signedDecode<4>(stream);
617
142k
            if (scheme == EncoderFast)  // use decaying first and second moment
618
0
            {
619
0
              uint32_t const t = abs(s);
620
0
              context = std::make_pair(((context.first * 15u + 7u) >> 4) + t, ((context.second * 15u + 7u) >> 4) + square(std::min(t, 4096u)));
621
0
              if (!s == !runCoder)
622
0
                runCoder = context.first < 1 ? 4 : context.first < 2 ? 3 : context.first < 4 ? 2 : context.first < 8 ? 1 : 0;
623
0
            }
624
142k
            else if (!s == !runCoder)
625
16.7k
              runCoder = q == 1024 ? context.first < 2u ? 1 : 0 : (context.first < 4u && context.second < 2u) ? 4 : (context.first < 8u
626
13.2k
              && context.second < 4u) ? 3 : (2u * sumSq < 3u * context.second + 48u) ? 2 : (2u * sumSq < 5u * context.second + 32u) ? 1 : 0;
627
142k
          }
628
175k
          if (run == 0 && s <= 0)
629
7.36k
            -- s; // s can't be zero, so shift negatives by 1
630
175k
          run = -1;
631
175k
        }
632
515k
        base[x] = s;
633
515k
      }
634
963
    }
635
48
  }
636
637
  template<typename T> void shiftVector(T * data, int shift, int count)
638
1.16k
  {
639
1.16k
    OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
640
32.7M
    for (int i = 0; i < count; ++ i)
641
32.7M
      data[i] >>= shift;
642
1.16k
  }
643
644
  template<typename I, typename A> void transformTerm(int const * & pc, A * destination, A const * auxData, int const bufferSize,
645
    I const & imageData, Header const & header, std::vector<int> const & isChroma, int boost)
646
709k
  {
647
1.80M
    while (*pc >= 0)
648
1.09M
    {
649
1.09M
      int const c = *(pc ++);
650
1.09M
      A const factor = *(pc ++);
651
1.09M
      if (isChroma[c] == -1)
652
301k
      {
653
301k
        auto layer = imageData + ((c / header.channels) * bufferSize * header.channels + c % header.channels);
654
301k
        A const boostFactor = boost * factor;
655
301k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
656
2.97G
        for (int i = 0; i < bufferSize; ++ i)
657
2.96G
          destination[i] += layer[i * header.channels] * boostFactor;
658
301k
      }
659
792k
      else
660
792k
      {
661
792k
        A const * auxDataC = auxData + c * bufferSize;
662
792k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
663
5.76G
        for (int i = 0; i < bufferSize; ++ i)
664
5.76G
          destination[i] += auxDataC[i] * factor;
665
792k
      }
666
1.09M
    }
667
709k
    A const denom = *((++ pc) ++);
668
709k
    if (denom == 2)
669
320
      shiftVector(destination, 1, bufferSize);
670
709k
    else if (denom == 4)
671
619
      shiftVector(destination, 2, bufferSize);
672
708k
    else if (denom == 8)
673
225
      shiftVector(destination, 3, bufferSize);
674
708k
    else if (denom > 1)  // [NOTE] disallow non-positive denominators
675
457k
    {
676
457k
      OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
677
1.86G
      for (int i = 0; i < bufferSize; ++ i)
678
1.86G
        destination[i] /= denom;
679
457k
    }
680
709k
  }
void GFWX::transformTerm<unsigned char const*, short>(int const*&, short*, short const*, int, unsigned char const* const&, GFWX::Header const&, std::__1::vector<int, std::__1::allocator<int> > const&, int)
Line
Count
Source
646
2.31k
  {
647
5.61k
    while (*pc >= 0)
648
3.30k
    {
649
3.30k
      int const c = *(pc ++);
650
3.30k
      A const factor = *(pc ++);
651
3.30k
      if (isChroma[c] == -1)
652
1.54k
      {
653
1.54k
        auto layer = imageData + ((c / header.channels) * bufferSize * header.channels + c % header.channels);
654
1.54k
        A const boostFactor = boost * factor;
655
1.54k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
656
38.7M
        for (int i = 0; i < bufferSize; ++ i)
657
38.7M
          destination[i] += layer[i * header.channels] * boostFactor;
658
1.54k
      }
659
1.76k
      else
660
1.76k
      {
661
1.76k
        A const * auxDataC = auxData + c * bufferSize;
662
1.76k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
663
50.8M
        for (int i = 0; i < bufferSize; ++ i)
664
50.8M
          destination[i] += auxDataC[i] * factor;
665
1.76k
      }
666
3.30k
    }
667
2.31k
    A const denom = *((++ pc) ++);
668
2.31k
    if (denom == 2)
669
225
      shiftVector(destination, 1, bufferSize);
670
2.08k
    else if (denom == 4)
671
545
      shiftVector(destination, 2, bufferSize);
672
1.54k
    else if (denom == 8)
673
225
      shiftVector(destination, 3, bufferSize);
674
1.31k
    else if (denom > 1)  // [NOTE] disallow non-positive denominators
675
0
    {
676
0
      OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
677
0
      for (int i = 0; i < bufferSize; ++ i)
678
0
        destination[i] /= denom;
679
0
    }
680
2.31k
  }
void GFWX::transformTerm<unsigned char*, short>(int const*&, short*, short const*, int, unsigned char* const&, GFWX::Header const&, std::__1::vector<int, std::__1::allocator<int> > const&, int)
Line
Count
Source
646
707k
  {
647
1.79M
    while (*pc >= 0)
648
1.09M
    {
649
1.09M
      int const c = *(pc ++);
650
1.09M
      A const factor = *(pc ++);
651
1.09M
      if (isChroma[c] == -1)
652
299k
      {
653
299k
        auto layer = imageData + ((c / header.channels) * bufferSize * header.channels + c % header.channels);
654
299k
        A const boostFactor = boost * factor;
655
299k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
656
2.93G
        for (int i = 0; i < bufferSize; ++ i)
657
2.93G
          destination[i] += layer[i * header.channels] * boostFactor;
658
299k
      }
659
790k
      else
660
790k
      {
661
790k
        A const * auxDataC = auxData + c * bufferSize;
662
790k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
663
5.71G
        for (int i = 0; i < bufferSize; ++ i)
664
5.71G
          destination[i] += auxDataC[i] * factor;
665
790k
      }
666
1.09M
    }
667
707k
    A const denom = *((++ pc) ++);
668
707k
    if (denom == 2)
669
95
      shiftVector(destination, 1, bufferSize);
670
707k
    else if (denom == 4)
671
74
      shiftVector(destination, 2, bufferSize);
672
707k
    else if (denom == 8)
673
0
      shiftVector(destination, 3, bufferSize);
674
707k
    else if (denom > 1)  // [NOTE] disallow non-positive denominators
675
457k
    {
676
457k
      OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
677
1.86G
      for (int i = 0; i < bufferSize; ++ i)
678
1.86G
        destination[i] /= denom;
679
457k
    }
680
707k
  }
681
682
  // GFWX_TRANSFORM_UYV implements YUV (actually UYV) as R -= G (chroma); B -= G (chroma); G += (R + B) / 4 (luma)
683
3.15k
  #define GFWX_TRANSFORM_UYV { 0, 1, -1, -1, 1, 1, 2, 1, -1, -1, 1, 1, 1, 0, 1, 2, 1, -1, 4, 0, -1 }
684
  // GFWX_TRANSFORM_A710 implements A710 as R -= G (chroma); B -= (G * 2 + R) / 2 (chroma); G += (B * 2 + R * 3) / 8 (luma)
685
3.15k
  #define GFWX_TRANSFORM_A710_BGR { 2, 1, -1, -1, 1, 1, 0, 1, -2, 2, -1, -1, 2, 1, 1, 0, 2, 2, 3, -1, 8, 0, -1 }
686
3.15k
  #define GFWX_TRANSFORM_A710_RGB { 0, 1, -1, -1, 1, 1, 2, 1, -2, 0, -1, -1, 2, 1, 1, 2, 2, 0, 3, -1, 8, 0, -1 }
687
688
  template<typename I> ptrdiff_t compress(I const & imageData, Header & header, uint8_t * buffer, size_t size,
689
    int const * channelTransform, uint8_t * metaData, size_t metaDataSize)
690
2.94k
  {
691
2.94k
    typedef typename std::remove_reference<decltype(imageData[0])>::type base;
692
2.94k
    typedef typename std::conditional<sizeof(base) < 2, int16_t, int32_t>::type aux;
693
2.94k
    if (header.sizex > (1 << 30) || header.sizey > (1 << 30))  // [NOTE] current implementation can't go over 2^30
694
0
      return ErrorMalformed;
695
2.94k
    Bits stream(reinterpret_cast<uint32_t *>(buffer), reinterpret_cast<uint32_t *>(buffer) + size / 4);
696
2.94k
    stream.putBits('G' | ('F' << 8) | ('W' << 16) | ('X' << 24), 32);
697
2.94k
    stream.putBits(header.version = 1, 32);
698
2.94k
    stream.putBits(header.sizex, 32);
699
2.94k
    stream.putBits(header.sizey, 32);
700
2.94k
    stream.putBits(header.layers - 1, 16);
701
2.94k
    stream.putBits(header.channels - 1, 16);
702
2.94k
    stream.putBits((header.bitDepth ? header.bitDepth : (header.bitDepth = std::numeric_limits<base>::digits)) - 1, 8);
703
2.94k
    stream.putBits(header.isSigned = std::numeric_limits<base>::is_signed ? 1 : 0, 1);
704
2.94k
    stream.putBits(header.quality - 1, 10);
705
2.94k
    stream.putBits(header.chromaScale - 1, 8);
706
2.94k
    stream.putBits(header.blockSize - 2, 5);
707
2.94k
    stream.putBits(header.filter, 8);
708
2.94k
    stream.putBits(header.quantization, 8);
709
2.94k
    stream.putBits(header.encoder, 8);
710
2.94k
    stream.putBits(header.intent, 8);
711
2.94k
    stream.putBits(int(metaDataSize / 4), 32);
712
2.94k
    stream.buffer = std::copy(reinterpret_cast<uint32_t *>(metaData), reinterpret_cast<uint32_t *>(metaData) + metaDataSize / 4, stream.buffer);
713
2.94k
    int const bufferSize = header.sizex * header.sizey;
714
2.94k
    std::vector<aux> auxData((size_t)header.layers * header.channels * bufferSize, 0);
715
2.94k
    std::vector<int> isChroma(header.layers * header.channels, -1);
716
2.94k
    int const chromaQuality = std::max(1, (header.quality + header.chromaScale / 2) / header.chromaScale);
717
2.94k
    int const boost = header.quality == QualityMax ? 1 : 8; // [NOTE] due to Cubic lifting max multiplier of 20, boost * 20 must be less than 256
718
2.94k
    if (channelTransform)  // run color transform program (and also encode it to the file)
719
770
    {
720
770
      int const * pc = channelTransform;
721
3.08k
      while (*pc >= 0)
722
2.31k
      {
723
2.31k
        int const c = *(pc ++);
724
2.31k
        aux * destination = &auxData[c * bufferSize];
725
2.31k
        transformTerm(pc, destination, &auxData[0], bufferSize, imageData, header, isChroma, boost);
726
2.31k
        auto layer = imageData + ((c / header.channels) * bufferSize * header.channels + c % header.channels);
727
2.31k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
728
58.1M
        for (int i = 0; i < bufferSize; ++ i)
729
58.1M
          destination[i] += layer[i * header.channels] * boost;
730
2.31k
        isChroma[c] = *(pc ++);
731
2.31k
      }
732
17.3k
      for (int const * i = channelTransform; i <= pc; ++ i)
733
16.6k
        signedCode<2>(*i, stream);
734
770
    }
735
2.17k
    else
736
2.17k
      signedCode<2>(-1, stream);
737
2.94k
    stream.flushWriteWord();
738
11.7k
    for (int c = 0; c < header.layers * header.channels; ++ c) if (isChroma[c] == -1)  // copy channels having no transform
739
6.52k
    {
740
6.52k
      aux * destination = &auxData[c * bufferSize];
741
6.52k
      auto layer = imageData + ((c / header.channels) * bufferSize * header.channels + c % header.channels);
742
6.52k
      OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
743
60.2M
      for (int i = 0; i < bufferSize; ++ i)
744
60.2M
        destination[i] = layer[i * header.channels] * boost;
745
6.52k
      isChroma[c] = 0;
746
6.52k
    }
747
11.7k
    for (int c = 0; c < header.layers * header.channels; ++ c)  // lift and quantize the channels
748
8.83k
    {
749
8.83k
      Image<aux> auxImage(&auxData[c * bufferSize], header.sizex, header.sizey);
750
8.83k
      lift(auxImage, 0, 0, header.sizex, header.sizey, 1, header.filter);
751
8.83k
      if (header.intent >= IntentBayerRGGB && header.intent <= IntentBayerGeneric)
752
4.19k
      {
753
20.9k
        for (int ox = 0; ox <= 1; ++ ox) for (int oy = 1 - ox; oy <= 1; ++ oy)
754
12.5k
          lift(auxImage, ox, oy, header.sizex, header.sizey, 2, header.filter);
755
25.1k
        for (int ox = 0; ox <= 1; ++ ox) for (int oy = 0; oy <= 1; ++ oy)
756
16.7k
          quantize<aux, false>(auxImage, ox, oy, header.sizex, header.sizey, 2,
757
16.7k
            (ox | oy) ? chromaQuality : header.quality, header.quality, QualityMax * boost);
758
4.19k
      }
759
4.63k
      else
760
4.63k
        quantize<aux, false>(auxImage, 0, 0, header.sizex, header.sizey, 1, isChroma[c] ? chromaQuality : header.quality, 0, QualityMax * boost);
761
8.83k
    }
762
2.94k
    int step = 1;
763
16.7k
    while (step * 2 < header.sizex || step * 2 < header.sizey)
764
13.7k
      step *= 2;
765
13.4k
    for (bool hasDC = true; step >= 1; hasDC = false)
766
13.2k
    {
767
13.2k
      int64_t const bs = int64_t(step) << header.blockSize;
768
13.2k
      int const blockCountX = (header.sizex + bs - 1) / bs;
769
13.2k
      int const blockCountY = (header.sizey + bs - 1) / bs;
770
13.2k
      int const blockCount = blockCountX * blockCountY * header.layers * header.channels;
771
13.2k
      std::vector<Bits> streamBlock(blockCount, Bits(0, 0));
772
13.2k
      uint32_t * blockBegin = stream.buffer + blockCount; // leave space for block sizes
773
13.2k
      if (blockBegin >= stream.bufferEnd)
774
647
        return ErrorOverflow;
775
3.48M
      for (int block = 0; block < blockCount; ++ block)  // partition buffer into temporary regions for each block
776
3.47M
        streamBlock[block].buffer = blockBegin + (stream.bufferEnd - blockBegin) * block / blockCount;
777
3.48M
      for (int block = 0; block < blockCount; ++ block)
778
3.47M
        streamBlock[block].bufferEnd = block + 1 < blockCount ? streamBlock[block + 1].buffer : stream.bufferEnd;
779
12.5k
      OMP_PARALLEL_FOR(4) // [MAGIC] for some reason, 4 is by far the best option here
780
3.48M
      for (int block = 0; block < blockCount; ++ block)
781
3.47M
      {
782
3.47M
        int const bx = block % blockCountX, by = (block / blockCountX) % blockCountY, c = block / (blockCountX * blockCountY);
783
3.47M
        Image<aux> auxImage(&auxData[c * bufferSize], header.sizex, header.sizey);
784
3.47M
        if (header.intent < IntentBayerRGGB || header.intent > IntentBayerGeneric)
785
1.96M
          encode(auxImage, streamBlock[block], bx * bs, by * bs,
786
1.96M
          int(std::min((bx + 1) * bs, int64_t(header.sizex))), int(std::min((by + 1) * bs, int64_t(header.sizey))),
787
1.96M
          step, header.encoder, isChroma[c] ? chromaQuality : header.quality, hasDC && !bx && !by, isChroma[c] != 0);
788
9.07M
        else for (int ox = 0; ox <= 1; ++ ox) for (int oy = 0; oy <= 1; ++ oy)
789
6.05M
          encode(auxImage, streamBlock[block], bx * bs + ox, by * bs + oy,
790
6.05M
          int(std::min((bx + 1) * bs, int64_t(header.sizex))), int(std::min((by + 1) * bs, int64_t(header.sizey))),
791
6.05M
          2 * step, header.encoder, (ox || oy) ? chromaQuality : header.quality, hasDC && !bx && !by, ox || oy);
792
3.47M
        streamBlock[block].flushWriteWord();
793
3.47M
      }
794
2.14M
      for (int block = 0; block < blockCount; ++ block)  // check streamBlocks for overflow
795
2.13M
        if (streamBlock[block].indexBits < 0)
796
2.02k
          return ErrorOverflow;
797
2.09M
      for (int block = 0; block < blockCount; ++ block)  // encode block lengths [NOTE] this 32-bit encoding limits the file size to < 16 GB
798
2.08M
        *(stream.buffer ++) = uint32_t(streamBlock[block].buffer - (block ? streamBlock[block - 1].bufferEnd : blockBegin));
799
2.09M
      for (int block = 0; block < blockCount; ++ block)  // pack the streamBlock data tightly, by word [NOTE] first block is already packed
800
2.08M
        stream.buffer = block ? std::copy(streamBlock[block - 1].bufferEnd, streamBlock[block].buffer, stream.buffer) : streamBlock[0].buffer;
801
10.5k
      step /= 2;
802
10.5k
    }
803
274
    return reinterpret_cast<uint8_t *>(stream.buffer) - buffer; // return size in bytes
804
2.94k
  }
805
806
  template<typename I> ptrdiff_t decompress(I const & imageData, Header & header, uint8_t const * data, size_t size, int downsampling, bool test)
807
28
  {
808
28
    typedef typename std::remove_reference<decltype(imageData[0])>::type base;
809
28
    typedef typename std::conditional<sizeof(base) < 2, int16_t, int32_t>::type aux;
810
28
    Bits stream(reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(data)), reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(data)) + size / 4);
811
28
    if (size < 28)  // at least load the header
812
0
      return 28;
813
28
    if (stream.getBits(32) != uint32_t('G' | ('F' << 8) | ('W' << 16) | ('X' << 24)))
814
3
      return ErrorMalformed;
815
25
    header.version = stream.getBits(32);
816
25
    header.sizex = stream.getBits(32);
817
25
    header.sizey = stream.getBits(32);
818
25
    header.layers = stream.getBits(16) + 1;
819
25
    header.channels = stream.getBits(16) + 1;
820
25
    header.bitDepth = stream.getBits(8) + 1;
821
25
    header.isSigned = stream.getBits(1);
822
25
    header.quality = stream.getBits(10) + 1;
823
25
    header.chromaScale = stream.getBits(8) + 1;
824
25
    header.blockSize = stream.getBits(5) + 2;
825
25
    header.filter = stream.getBits(8);
826
25
    header.quantization = stream.getBits(8);
827
25
    header.encoder = stream.getBits(8);
828
25
    header.intent = stream.getBits(8);
829
25
    if (header.sizex < 0 || header.sizex > (1 << 30) || header.sizey < 0 || header.sizey > (1 << 30) || header.bufferSize() == 0)
830
1
      return ErrorMalformed;  // [NOTE] current implementation can't go over 2^30
831
24
    if (!imageData)    // just header
832
12
      return ResultOk;
833
12
    if (header.isSigned != (std::numeric_limits<base>::is_signed ? 1 : 0) || header.bitDepth > std::numeric_limits<base>::digits)
834
0
      return ErrorTypeMismatch; // check for correct buffer type (though doesn't test the buffer size)
835
    // [NOTE] clients can read metadata themselves by accessing the size (in words) at word[7] and the metadata at word[8+]
836
12
    if ((stream.buffer += stream.getBits(32)) >= stream.bufferEnd) // skip metadata
837
0
      return reinterpret_cast<uint8_t *>(stream.buffer) - data; // suggest point of interest to skip metadata
838
12
    int const sizexDown = (header.sizex + (1 << downsampling) - 1) >> downsampling, sizeyDown = (header.sizey + (1 << downsampling) - 1) >> downsampling;
839
12
    int const bufferSize = sizexDown * sizeyDown;
840
12
    std::vector<aux> auxData((size_t)header.layers * header.channels * bufferSize, 0);
841
12
    std::vector<int> isChroma(header.layers * header.channels, 0), transformProgram, transformSteps;
842
12
    size_t nextPointOfInterest = size + 1024; // guess next point of interest [NOTE] may be larger than the complete file
843
707k
    while (true)  // decode color transform program (including isChroma flags)
844
707k
    {
845
707k
      transformProgram.push_back(signedDecode<2>(stream));  // channel
846
707k
      if (transformProgram.back() >= static_cast<int>(isChroma.size()))
847
0
          return ErrorMalformed;
848
707k
      if (transformProgram.back() < 0)
849
12
        break;
850
707k
      transformSteps.push_back(int(transformProgram.size()) - 1);
851
1.79M
      while (true)
852
1.79M
      {
853
1.79M
        if (stream.indexBits < 0)  // test for truncation
854
0
          return nextPointOfInterest; // need more data
855
1.79M
        transformProgram.push_back(signedDecode<2>(stream));  // other channel
856
1.79M
        if (transformProgram.back() >= static_cast<int>(isChroma.size()))
857
0
            return ErrorMalformed;
858
1.79M
        if (transformProgram.back() < 0)
859
707k
          break;
860
1.09M
        transformProgram.push_back(signedDecode<2>(stream));  // factor
861
1.09M
      }
862
707k
      transformProgram.push_back(signedDecode<2>(stream));  // denominator
863
707k
      transformProgram.push_back(signedDecode<2>(stream));  // chroma flag
864
707k
      isChroma[transformProgram[transformSteps.back()]] = transformProgram.back();
865
707k
    }
866
12
    stream.flushReadWord();
867
12
    int const chromaQuality = std::max(1, (header.quality + header.chromaScale / 2) / header.chromaScale);
868
12
    int const boost = header.quality == QualityMax ? 1 : 8; // [NOTE] due to Cubic lifting max multiplier of 20, boost * 20 must be less than 256
869
12
    bool isTruncated = false;
870
12
    int step = 1;
871
109
    while (step * 2 < header.sizex || step * 2 < header.sizey)
872
97
      step *= 2;
873
60
    for (bool hasDC = true; (step >> downsampling) >= 1; hasDC = false)  // decode just enough coefficients for downsampled image
874
58
    {
875
58
      int64_t const bs = int64_t(step) << header.blockSize;
876
58
      int const blockCountX = int((header.sizex + bs - 1) / bs);
877
58
      int const blockCountY = int((header.sizey + bs - 1) / bs);
878
58
      int const blockCount = blockCountX * blockCountY * header.layers * header.channels;
879
58
      isTruncated = true;
880
58
      if (stream.buffer + 1 + blockCount > stream.bufferEnd)  // check for enough buffer to read block sizes
881
7
        break;
882
51
      std::vector<Bits> streamBlock(blockCount, Bits(0, 0));
883
196
      for (int block = 0; block < blockCount; ++ block)  // first, read sizes into bufferEnd pointers
884
145
        streamBlock[block].bufferEnd = static_cast<uint32_t *>(0) + *(stream.buffer ++);
885
196
      for (int block = 0; block < blockCount; ++ block)  // then convert sizes to true buffer pointers
886
145
        streamBlock[block].bufferEnd = (streamBlock[block].buffer = block ? streamBlock[block - 1].bufferEnd : stream.buffer)
887
145
                        + (streamBlock[block].bufferEnd - static_cast<uint32_t *>(0));
888
51
      stream.buffer = streamBlock[blockCount - 1].bufferEnd;
889
51
      nextPointOfInterest = reinterpret_cast<uint8_t *>(stream.buffer + ((step >> downsampling) > 1 ? blockCount * 4 : 0)) - data;
890
51
      if (stream.buffer <= stream.bufferEnd)
891
48
        isTruncated = false;
892
51
      int const stepDown = step >> downsampling;
893
51
      int64_t const bsDown = int64_t(stepDown) << header.blockSize;
894
51
      OMP_PARALLEL_FOR(4) // [MAGIC] for some reason, 4 is by far the best option here
895
196
      for (int block = 0; block < blockCount; ++ block) if (!test && streamBlock[block].bufferEnd <= stream.bufferEnd)
896
48
      {
897
48
        int const bx = block % blockCountX, by = (block / blockCountX) % blockCountY, c = block / (blockCountX * blockCountY);
898
48
        Image<aux> auxImage(&auxData[c * bufferSize], sizexDown, sizeyDown);
899
48
        if (header.intent < IntentBayerRGGB || header.intent > IntentBayerGeneric)
900
48
          decode(auxImage, streamBlock[block], int(bx * bsDown), int(by * bsDown),
901
48
          int(std::min((bx + 1) * bsDown, int64_t(sizexDown))), int(std::min((by + 1) * bsDown, int64_t(sizeyDown))),
902
48
          stepDown, header.encoder, isChroma[c] ? chromaQuality : header.quality, hasDC && !bx && !by, isChroma[c] != 0);
903
0
        else for (int ox = 0; ox <= 1; ++ ox) for (int oy = 0; oy <= 1; ++ oy)
904
0
          decode(auxImage, streamBlock[block], int(bx * bsDown + ox), int(by * bsDown + oy),
905
0
          int(std::min((bx + 1) * bsDown, int64_t(sizexDown))), int(std::min((by + 1) * bsDown, int64_t(sizeyDown))),
906
0
          2 * stepDown, header.encoder, (ox || oy) ? chromaQuality : header.quality, hasDC && !bx && !by, ox || oy);
907
48
      }
908
193
      for (int block = 0; block < blockCount; ++ block)  // check if any blocks ran out of buffer, which should not happen on valid files
909
145
        if (streamBlock[block].indexBits < 0)
910
3
          return ErrorMalformed;
911
48
      step /= 2;
912
48
    }
913
9
    if (test)
914
0
      return isTruncated ? nextPointOfInterest : ResultOk; // return next point of interest if the data was truncated prior to completing request
915
461
    for (int c = 0; c < header.layers * header.channels; ++ c)  // dequantize and unlift the channels
916
452
    {
917
452
      Image<aux> auxImage(&auxData[c * bufferSize], sizexDown, sizeyDown);
918
452
      if (header.intent >= IntentBayerRGGB && header.intent <= IntentBayerGeneric)
919
30
      {
920
180
        for (int ox = 0; ox <= 1; ++ ox) for (int oy = 0; oy <= 1; ++ oy)
921
120
          quantize<aux, true>(auxImage, ox, oy, sizexDown, sizeyDown, 2,
922
120
            ((ox | oy) ? chromaQuality : header.quality) << downsampling, header.quality, QualityMax * boost);
923
150
        for (int ox = 0; ox <= 1; ++ ox) for (int oy = 1 - ox; oy <= 1; ++ oy)
924
90
          unlift(auxImage, ox, oy, sizexDown, sizeyDown, 2, header.filter);
925
30
      }
926
422
      else
927
422
        quantize<aux, true>(auxImage, 0, 0, sizexDown, sizeyDown, 1,
928
422
          (isChroma[c] ? chromaQuality : header.quality) << downsampling, 0, QualityMax * boost);
929
452
      unlift(auxImage, 0, 0, sizexDown, sizeyDown, 1, header.filter);
930
452
    }
931
707k
    for (int s = (int)transformSteps.size() - 1; s >= 0; -- s)  // run color transform program in reverse
932
707k
    {
933
707k
      int const * pc = &transformProgram[transformSteps[s]];
934
707k
      int const c = *(pc ++);
935
707k
      std::vector<aux> transformTemp(bufferSize, 0);
936
707k
      transformTerm(pc, &transformTemp[0], &auxData[0], bufferSize, imageData, header, isChroma, boost);
937
707k
      aux * destination = &auxData[c * bufferSize];
938
707k
      OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
939
4.68G
      for (int i = 0; i < bufferSize; ++ i)
940
4.68G
        destination[i] -= transformTemp[i];
941
707k
    }
942
461
    for (int c = 0; c < header.layers * header.channels; ++ c)  // copy the channels to the destination buffer
943
452
    {
944
452
      aux * destination = &auxData[c * bufferSize];
945
452
      auto layer = imageData + ((c / header.channels) * bufferSize * header.channels + c % header.channels);
946
452
      if (boost == 1)
947
0
      {
948
0
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
949
0
        for (int i = 0; i < bufferSize; ++ i)
950
0
          layer[i * header.channels] = static_cast<base>(std::max(static_cast<aux>(std::numeric_limits<base>::lowest()),
951
0
            std::min(static_cast<aux>(std::numeric_limits<base>::max()), static_cast<aux>(destination[i]))));
952
0
      }
953
452
      else
954
452
      {
955
452
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
956
2.89M
        for (int i = 0; i < bufferSize; ++ i)
957
2.89M
          layer[i * header.channels] = static_cast<base>(std::max(static_cast<aux>(std::numeric_limits<base>::lowest()),
958
2.89M
            std::min(static_cast<aux>(std::numeric_limits<base>::max()), static_cast<aux>(destination[i] / boost))));
959
452
      }
960
452
      if (header.quality < QualityMax && header.intent >= IntentBayerRGGB && header.intent <= IntentBayerGBRG)  // check if Bayer cleanup is required
961
30
      {
962
30
        int const bayerNoiseThresh = ((QualityMax + header.quality / 2) / header.quality + (QualityMax + chromaQuality / 2) / chromaQuality) * 2;
963
30
        Image<aux> auxImage(&auxData[c * bufferSize], sizexDown, sizeyDown);
964
30
        OMP_PARALLEL_FOR(ThreadIterations)
965
30
        for (int y = 1; y < sizeyDown - 1; ++ y)
966
0
          for (int x = 1 + (y + (header.intent == IntentBayerGBRG || header.intent == IntentBayerGRBG ? 1 : 0)) % 2; x < sizexDown - 1; x += 2)
967
0
          {
968
0
            aux s = auxImage[y][x];
969
0
            aux sum = s * 4;
970
0
            int count = 4;
971
0
            for (int oy = -1; oy <= 1; oy += 2) for (int ox = -1; ox <= 1; ox += 2)
972
0
            {
973
0
              aux t = auxImage[y + oy][x + ox];
974
0
              if (abs(s - t) > bayerNoiseThresh)
975
0
                continue;
976
0
              sum += t;
977
0
              ++ count;
978
0
            }
979
0
            layer[(y * sizexDown + x) * header.channels]
980
0
              = static_cast<base>(std::max(static_cast<aux>(std::numeric_limits<base>::lowest()),
981
0
                std::min(static_cast<aux>(std::numeric_limits<base>::max()), aux((sum + count / 2) / (count * boost)))));
982
0
          }
983
30
      }
984
452
    }
985
9
    return isTruncated ? nextPointOfInterest : ResultOk; // return next point of interest if the data was truncated prior to completing request
986
9
  }
987
}