Coverage Report

Created: 2024-11-21 06:36

/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
15
    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
3.04k
      : sizex(sizex), sizey(sizey), layers(layers), channels(channels), bitDepth(bitDepth), quality(std::max(1, std::min(int(QualityMax), quality))),
84
3.04k
      chromaScale(std::max(1, std::min(256, chromaScale))), blockSize(std::min(30, std::max(2, blockSize))), filter(std::min(255, filter)),
85
3.04k
      quantization(std::min(255, quantization)), encoder(std::min(255, encoder)), intent(std::min(255, intent)) {}
86
    size_t bufferSize() const
87
23
    {
88
23
      size_t const part1 = static_cast<size_t>(sizex) * sizey;
89
23
      size_t const part2 = static_cast<size_t>(channels) * layers * ((bitDepth + 7) / 8);
90
23
      return std::log(part1) + std::log(part2) > std::log(std::numeric_limits<size_t>::max() - 1) ? 0 : part1 * part2;
91
23
    }
92
  };
93
94
  template<typename T> struct Image // handy wrapper for 2D image data
95
  {
96
    T * data;
97
    int sizex, sizey;
98
3.51M
    Image(T * data, int sizex, int sizey) : data(data), sizex(sizex), sizey(sizey) {}
99
740M
    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.80M
    {
110
9.80M
      int newBits = indexBits + bits;
111
9.80M
      if (buffer == bufferEnd)
112
63.4k
        return indexBits = -1;  // signify overflow
113
9.73M
      uint32_t x = *buffer << indexBits;
114
9.73M
      if (newBits >= 32)
115
483k
      {
116
483k
        ++ buffer;
117
483k
        if ((newBits -= 32) > 0)
118
7.15k
        {
119
7.15k
          if (buffer == bufferEnd)
120
1
            return indexBits = -1;  // signify overflow
121
7.15k
          x |= *buffer >> (32 - indexBits);
122
7.15k
        }
123
483k
      }
124
9.73M
      indexBits = newBits;
125
9.73M
      return x >> (32 - bits);
126
9.73M
    }
127
    void putBits(uint32_t x, int bits)
128
58.1M
    {
129
58.1M
      int newBits = indexBits + bits;
130
58.1M
      if (buffer == bufferEnd)
131
10.7M
        newBits = -1;  // signify overflow
132
47.3M
      else if (newBits < 32)
133
36.1M
        (writeCache <<= bits) |= x;
134
11.1M
      else if (bits == 32 && newBits == 32)
135
13.8k
      {
136
13.8k
        newBits = 0;
137
13.8k
        *(buffer ++) = x;
138
13.8k
      }
139
11.1M
      else
140
11.1M
      {
141
11.1M
        newBits -= 32;
142
11.1M
        *(buffer ++) = (writeCache << (bits - newBits)) | (x >> newBits);
143
11.1M
        writeCache = x;
144
11.1M
      }
145
58.1M
      indexBits = newBits;
146
58.1M
    }
147
    uint32_t getZeros(uint32_t maxZeros)
148
5.33M
    {
149
5.33M
      int newBits = indexBits;
150
5.33M
      if (buffer == bufferEnd)
151
99.3k
        return indexBits = -1;  // signify overflow
152
5.23M
      uint32_t b = *buffer;
153
5.23M
      uint32_t x = 0;
154
6.69M
      while (true)
155
6.69M
      {
156
6.69M
        if (newBits == 31)
157
194k
        {
158
194k
          ++ buffer;
159
194k
          if ((b & 1u) || (++ x == maxZeros))
160
155k
          {
161
155k
            indexBits = 0;
162
155k
            return x;
163
155k
          }
164
39.7k
          if (buffer == bufferEnd)
165
0
            return indexBits = -1; // signify overflow
166
39.7k
          b = *buffer;
167
39.7k
          newBits = 0;
168
39.7k
          continue;
169
39.7k
        }
170
6.49M
        if (((b << newBits) & (1u << 31)) || (++ x == maxZeros))
171
5.08M
        {
172
5.08M
          indexBits = newBits + 1;
173
5.08M
          return x;
174
5.08M
        }
175
1.41M
        ++ newBits;
176
1.41M
      }
177
5.23M
    }
178
    void flushWriteWord() // [NOTE] does not clear overflow
179
3.50M
    {
180
3.50M
      putBits(0, (32 - indexBits) % 32);
181
3.50M
    }
182
    void flushReadWord()  // [NOTE] does not clear overflow
183
11
    {
184
11
      if (indexBits <= 0)
185
5
        return;
186
6
      ++ buffer;
187
6
      indexBits = 0;
188
6
    }
189
  };
190
191
  template<int pot> void unsignedCode(uint32_t x, Bits & stream)  // limited length power-of-two Golomb-Rice code
192
43.9M
  {
193
43.9M
    uint32_t const y = x >> (pot);
194
43.9M
    if (y >= 12)
195
13.2M
    {
196
13.2M
      stream.putBits(0, 12);  // escape to larger code
197
13.2M
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
13.2M
    }
199
30.6M
    else
200
30.6M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
43.9M
  }
void GFWX::unsignedCode<2>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
725k
  {
193
725k
    uint32_t const y = x >> (pot);
194
725k
    if (y >= 12)
195
68.1k
    {
196
68.1k
      stream.putBits(0, 12);  // escape to larger code
197
68.1k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
68.1k
    }
199
656k
    else
200
656k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
725k
  }
void GFWX::unsignedCode<6>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
68.1k
  {
193
68.1k
    uint32_t const y = x >> (pot);
194
68.1k
    if (y >= 12)
195
10.7k
    {
196
10.7k
      stream.putBits(0, 12);  // escape to larger code
197
10.7k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
10.7k
    }
199
57.3k
    else
200
57.3k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
68.1k
  }
void GFWX::unsignedCode<10>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
10.7k
  {
193
10.7k
    uint32_t const y = x >> (pot);
194
10.7k
    if (y >= 12)
195
888
    {
196
888
      stream.putBits(0, 12);  // escape to larger code
197
888
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
888
    }
199
9.90k
    else
200
9.90k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
10.7k
  }
void GFWX::unsignedCode<14>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
888
  {
193
888
    uint32_t const y = x >> (pot);
194
888
    if (y >= 12)
195
36
    {
196
36
      stream.putBits(0, 12);  // escape to larger code
197
36
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
36
    }
199
852
    else
200
852
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
888
  }
void GFWX::unsignedCode<18>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
36
  {
193
36
    uint32_t const y = x >> (pot);
194
36
    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
36
    else
200
36
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
36
  }
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
14.1M
  {
193
14.1M
    uint32_t const y = x >> (pot);
194
14.1M
    if (y >= 12)
195
5.34M
    {
196
5.34M
      stream.putBits(0, 12);  // escape to larger code
197
5.34M
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
5.34M
    }
199
8.76M
    else
200
8.76M
      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.1M
  }
void GFWX::unsignedCode<5>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
5.34M
  {
193
5.34M
    uint32_t const y = x >> (pot);
194
5.34M
    if (y >= 12)
195
2.24M
    {
196
2.24M
      stream.putBits(0, 12);  // escape to larger code
197
2.24M
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
2.24M
    }
199
3.09M
    else
200
3.09M
      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.34M
  }
void GFWX::unsignedCode<9>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
2.24M
  {
193
2.24M
    uint32_t const y = x >> (pot);
194
2.24M
    if (y >= 12)
195
11.4k
    {
196
11.4k
      stream.putBits(0, 12);  // escape to larger code
197
11.4k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
11.4k
    }
199
2.23M
    else
200
2.23M
      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.24M
  }
void GFWX::unsignedCode<13>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
11.4k
  {
193
11.4k
    uint32_t const y = x >> (pot);
194
11.4k
    if (y >= 12)
195
70
    {
196
70
      stream.putBits(0, 12);  // escape to larger code
197
70
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
70
    }
199
11.3k
    else
200
11.3k
      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.4k
  }
void GFWX::unsignedCode<17>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
70
  {
193
70
    uint32_t const y = x >> (pot);
194
70
    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
70
    else
200
70
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
70
  }
Unexecuted instantiation: void GFWX::unsignedCode<21>(unsigned int, GFWX::Bits&)
void GFWX::unsignedCode<3>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
1.05M
  {
193
1.05M
    uint32_t const y = x >> (pot);
194
1.05M
    if (y >= 12)
195
126k
    {
196
126k
      stream.putBits(0, 12);  // escape to larger code
197
126k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
126k
    }
199
926k
    else
200
926k
      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.05M
  }
void GFWX::unsignedCode<7>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
126k
  {
193
126k
    uint32_t const y = x >> (pot);
194
126k
    if (y >= 12)
195
12.0k
    {
196
12.0k
      stream.putBits(0, 12);  // escape to larger code
197
12.0k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
12.0k
    }
199
114k
    else
200
114k
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
126k
  }
void GFWX::unsignedCode<11>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
12.0k
  {
193
12.0k
    uint32_t const y = x >> (pot);
194
12.0k
    if (y >= 12)
195
178
    {
196
178
      stream.putBits(0, 12);  // escape to larger code
197
178
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
178
    }
199
11.8k
    else
200
11.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
12.0k
  }
void GFWX::unsignedCode<15>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
178
  {
193
178
    uint32_t const y = x >> (pot);
194
178
    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
178
    else
200
178
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
178
  }
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
12.6M
  {
193
12.6M
    uint32_t const y = x >> (pot);
194
12.6M
    if (y >= 12)
195
4.77M
    {
196
4.77M
      stream.putBits(0, 12);  // escape to larger code
197
4.77M
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
4.77M
    }
199
7.84M
    else
200
7.84M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
12.6M
  }
void GFWX::unsignedCode<8>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
4.77M
  {
193
4.77M
    uint32_t const y = x >> (pot);
194
4.77M
    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
4.69M
    else
200
4.69M
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
4.77M
  }
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
97
    {
196
97
      stream.putBits(0, 12);  // escape to larger code
197
97
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
97
    }
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
97
  {
193
97
    uint32_t const y = x >> (pot);
194
97
    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
97
    else
200
97
      stream.putBits((1 << (pot)) | (x & ~(~0u << (pot))), y + 1 + pot); // encode x / 2^pot in unary followed by x % 2^pot in binary
201
97
  }
Unexecuted instantiation: void GFWX::unsignedCode<20>(unsigned int, GFWX::Bits&)
void GFWX::unsignedCode<0>(unsigned int, GFWX::Bits&)
Line
Count
Source
192
2.73M
  {
193
2.73M
    uint32_t const y = x >> (pot);
194
2.73M
    if (y >= 12)
195
572k
    {
196
572k
      stream.putBits(0, 12);  // escape to larger code
197
572k
      unsignedCode<pot < 20 ? pot + 4 : 24>(x - (12 << (pot)), stream);
198
572k
    }
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.73M
  }
202
203
  template<int pot> uint32_t unsignedDecode(Bits & stream)
204
5.33M
  {
205
5.33M
    uint32_t x = stream.getZeros(12);
206
5.33M
    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.33M
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
5.33M
  }
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.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<10>(GFWX::Bits&)
Line
Count
Source
204
956
  {
205
956
    uint32_t x = stream.getZeros(12);
206
956
    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
956
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
956
  }
unsigned int GFWX::unsignedDecode<14>(GFWX::Bits&)
Line
Count
Source
204
926
  {
205
926
    uint32_t x = stream.getZeros(12);
206
926
    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
926
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
926
  }
unsigned int GFWX::unsignedDecode<18>(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<22>(GFWX::Bits&)
Line
Count
Source
204
911
  {
205
911
    uint32_t x = stream.getZeros(12);
206
911
    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
911
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
911
  }
unsigned int GFWX::unsignedDecode<26>(GFWX::Bits&)
Line
Count
Source
204
909
  {
205
909
    uint32_t x = stream.getZeros(12);
206
909
    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
909
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
909
  }
unsigned int GFWX::unsignedDecode<30>(GFWX::Bits&)
Line
Count
Source
204
907
  {
205
907
    uint32_t x = stream.getZeros(12);
206
907
    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
907
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
907
  }
unsigned int GFWX::unsignedDecode<34>(GFWX::Bits&)
Line
Count
Source
204
907
  {
205
907
    uint32_t x = stream.getZeros(12);
206
907
    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
907
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
907
  }
unsigned int GFWX::unsignedDecode<38>(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<42>(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<46>(GFWX::Bits&)
Line
Count
Source
204
898
  {
205
898
    uint32_t x = stream.getZeros(12);
206
898
    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
898
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
898
  }
unsigned int GFWX::unsignedDecode<50>(GFWX::Bits&)
Line
Count
Source
204
895
  {
205
895
    uint32_t x = stream.getZeros(12);
206
895
    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
895
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
895
  }
unsigned int GFWX::unsignedDecode<54>(GFWX::Bits&)
Line
Count
Source
204
895
  {
205
895
    uint32_t x = stream.getZeros(12);
206
895
    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
895
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
895
  }
unsigned int GFWX::unsignedDecode<58>(GFWX::Bits&)
Line
Count
Source
204
895
  {
205
895
    uint32_t x = stream.getZeros(12);
206
895
    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
895
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
895
  }
unsigned int GFWX::unsignedDecode<62>(GFWX::Bits&)
Line
Count
Source
204
893
  {
205
893
    uint32_t x = stream.getZeros(12);
206
893
    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
893
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
893
  }
unsigned int GFWX::unsignedDecode<66>(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<70>(GFWX::Bits&)
Line
Count
Source
204
874
  {
205
874
    uint32_t x = stream.getZeros(12);
206
874
    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
874
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
874
  }
unsigned int GFWX::unsignedDecode<74>(GFWX::Bits&)
Line
Count
Source
204
871
  {
205
871
    uint32_t x = stream.getZeros(12);
206
871
    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
871
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
871
  }
unsigned int GFWX::unsignedDecode<78>(GFWX::Bits&)
Line
Count
Source
204
871
  {
205
871
    uint32_t x = stream.getZeros(12);
206
871
    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
871
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
871
  }
unsigned int GFWX::unsignedDecode<82>(GFWX::Bits&)
Line
Count
Source
204
871
  {
205
871
    uint32_t x = stream.getZeros(12);
206
871
    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
871
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
871
  }
unsigned int GFWX::unsignedDecode<86>(GFWX::Bits&)
Line
Count
Source
204
869
  {
205
869
    uint32_t x = stream.getZeros(12);
206
869
    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
869
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
869
  }
unsigned int GFWX::unsignedDecode<90>(GFWX::Bits&)
Line
Count
Source
204
869
  {
205
869
    uint32_t x = stream.getZeros(12);
206
869
    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
869
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
869
  }
unsigned int GFWX::unsignedDecode<94>(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<98>(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<102>(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<106>(GFWX::Bits&)
Line
Count
Source
204
862
  {
205
862
    uint32_t x = stream.getZeros(12);
206
862
    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
862
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
862
  }
unsigned int GFWX::unsignedDecode<110>(GFWX::Bits&)
Line
Count
Source
204
862
  {
205
862
    uint32_t x = stream.getZeros(12);
206
862
    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
862
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
862
  }
unsigned int GFWX::unsignedDecode<1>(GFWX::Bits&)
Line
Count
Source
204
51.1k
  {
205
51.1k
    uint32_t x = stream.getZeros(12);
206
51.1k
    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
51.1k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
51.1k
  }
unsigned int GFWX::unsignedDecode<5>(GFWX::Bits&)
Line
Count
Source
204
5.23k
  {
205
5.23k
    uint32_t x = stream.getZeros(12);
206
5.23k
    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.23k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
5.23k
  }
unsigned int GFWX::unsignedDecode<9>(GFWX::Bits&)
Line
Count
Source
204
4.48k
  {
205
4.48k
    uint32_t x = stream.getZeros(12);
206
4.48k
    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.48k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
4.48k
  }
unsigned int GFWX::unsignedDecode<13>(GFWX::Bits&)
Line
Count
Source
204
3.80k
  {
205
3.80k
    uint32_t x = stream.getZeros(12);
206
3.80k
    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.80k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
3.80k
  }
unsigned int GFWX::unsignedDecode<17>(GFWX::Bits&)
Line
Count
Source
204
3.61k
  {
205
3.61k
    uint32_t x = stream.getZeros(12);
206
3.61k
    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.61k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
3.61k
  }
unsigned int GFWX::unsignedDecode<21>(GFWX::Bits&)
Line
Count
Source
204
3.11k
  {
205
3.11k
    uint32_t x = stream.getZeros(12);
206
3.11k
    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.11k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
3.11k
  }
unsigned int GFWX::unsignedDecode<25>(GFWX::Bits&)
Line
Count
Source
204
2.97k
  {
205
2.97k
    uint32_t x = stream.getZeros(12);
206
2.97k
    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.97k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.97k
  }
unsigned int GFWX::unsignedDecode<29>(GFWX::Bits&)
Line
Count
Source
204
2.88k
  {
205
2.88k
    uint32_t x = stream.getZeros(12);
206
2.88k
    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.88k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.88k
  }
unsigned int GFWX::unsignedDecode<33>(GFWX::Bits&)
Line
Count
Source
204
2.80k
  {
205
2.80k
    uint32_t x = stream.getZeros(12);
206
2.80k
    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.80k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.80k
  }
unsigned int GFWX::unsignedDecode<37>(GFWX::Bits&)
Line
Count
Source
204
2.71k
  {
205
2.71k
    uint32_t x = stream.getZeros(12);
206
2.71k
    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.71k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.71k
  }
unsigned int GFWX::unsignedDecode<41>(GFWX::Bits&)
Line
Count
Source
204
2.63k
  {
205
2.63k
    uint32_t x = stream.getZeros(12);
206
2.63k
    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.63k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.63k
  }
unsigned int GFWX::unsignedDecode<45>(GFWX::Bits&)
Line
Count
Source
204
2.59k
  {
205
2.59k
    uint32_t x = stream.getZeros(12);
206
2.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
2.59k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.59k
  }
unsigned int GFWX::unsignedDecode<49>(GFWX::Bits&)
Line
Count
Source
204
2.52k
  {
205
2.52k
    uint32_t x = stream.getZeros(12);
206
2.52k
    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.52k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.52k
  }
unsigned int GFWX::unsignedDecode<53>(GFWX::Bits&)
Line
Count
Source
204
2.46k
  {
205
2.46k
    uint32_t x = stream.getZeros(12);
206
2.46k
    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.46k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.46k
  }
unsigned int GFWX::unsignedDecode<57>(GFWX::Bits&)
Line
Count
Source
204
2.40k
  {
205
2.40k
    uint32_t x = stream.getZeros(12);
206
2.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
2.40k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.40k
  }
unsigned int GFWX::unsignedDecode<61>(GFWX::Bits&)
Line
Count
Source
204
2.35k
  {
205
2.35k
    uint32_t x = stream.getZeros(12);
206
2.35k
    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.35k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.35k
  }
unsigned int GFWX::unsignedDecode<65>(GFWX::Bits&)
Line
Count
Source
204
2.30k
  {
205
2.30k
    uint32_t x = stream.getZeros(12);
206
2.30k
    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.30k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.30k
  }
unsigned int GFWX::unsignedDecode<69>(GFWX::Bits&)
Line
Count
Source
204
2.24k
  {
205
2.24k
    uint32_t x = stream.getZeros(12);
206
2.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
2.24k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
2.24k
  }
unsigned int GFWX::unsignedDecode<73>(GFWX::Bits&)
Line
Count
Source
204
1.85k
  {
205
1.85k
    uint32_t x = stream.getZeros(12);
206
1.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
1.85k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.85k
  }
unsigned int GFWX::unsignedDecode<77>(GFWX::Bits&)
Line
Count
Source
204
1.81k
  {
205
1.81k
    uint32_t x = stream.getZeros(12);
206
1.81k
    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.81k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.81k
  }
unsigned int GFWX::unsignedDecode<81>(GFWX::Bits&)
Line
Count
Source
204
1.56k
  {
205
1.56k
    uint32_t x = stream.getZeros(12);
206
1.56k
    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.56k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.56k
  }
unsigned int GFWX::unsignedDecode<85>(GFWX::Bits&)
Line
Count
Source
204
1.54k
  {
205
1.54k
    uint32_t x = stream.getZeros(12);
206
1.54k
    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.54k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.54k
  }
unsigned int GFWX::unsignedDecode<89>(GFWX::Bits&)
Line
Count
Source
204
1.48k
  {
205
1.48k
    uint32_t x = stream.getZeros(12);
206
1.48k
    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.48k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.48k
  }
unsigned int GFWX::unsignedDecode<93>(GFWX::Bits&)
Line
Count
Source
204
1.13k
  {
205
1.13k
    uint32_t x = stream.getZeros(12);
206
1.13k
    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.13k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.13k
  }
unsigned int GFWX::unsignedDecode<97>(GFWX::Bits&)
Line
Count
Source
204
769
  {
205
769
    uint32_t x = stream.getZeros(12);
206
769
    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
769
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
769
  }
unsigned int GFWX::unsignedDecode<101>(GFWX::Bits&)
Line
Count
Source
204
620
  {
205
620
    uint32_t x = stream.getZeros(12);
206
620
    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
620
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
620
  }
unsigned int GFWX::unsignedDecode<105>(GFWX::Bits&)
Line
Count
Source
204
456
  {
205
456
    uint32_t x = stream.getZeros(12);
206
456
    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
456
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
456
  }
unsigned int GFWX::unsignedDecode<109>(GFWX::Bits&)
Line
Count
Source
204
421
  {
205
421
    uint32_t x = stream.getZeros(12);
206
421
    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
421
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
421
  }
unsigned int GFWX::unsignedDecode<3>(GFWX::Bits&)
Line
Count
Source
204
21.0k
  {
205
21.0k
    uint32_t x = stream.getZeros(12);
206
21.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
21.0k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
21.0k
  }
unsigned int GFWX::unsignedDecode<7>(GFWX::Bits&)
Line
Count
Source
204
160
  {
205
160
    uint32_t x = stream.getZeros(12);
206
160
    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
160
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
160
  }
unsigned int GFWX::unsignedDecode<11>(GFWX::Bits&)
Line
Count
Source
204
121
  {
205
121
    uint32_t x = stream.getZeros(12);
206
121
    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
121
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
121
  }
unsigned int GFWX::unsignedDecode<15>(GFWX::Bits&)
Line
Count
Source
204
99
  {
205
99
    uint32_t x = stream.getZeros(12);
206
99
    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
99
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
99
  }
unsigned int GFWX::unsignedDecode<19>(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<23>(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<27>(GFWX::Bits&)
Line
Count
Source
204
84
  {
205
84
    uint32_t x = stream.getZeros(12);
206
84
    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
84
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
84
  }
unsigned int GFWX::unsignedDecode<31>(GFWX::Bits&)
Line
Count
Source
204
83
  {
205
83
    uint32_t x = stream.getZeros(12);
206
83
    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
83
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
83
  }
unsigned int GFWX::unsignedDecode<35>(GFWX::Bits&)
Line
Count
Source
204
83
  {
205
83
    uint32_t x = stream.getZeros(12);
206
83
    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
83
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
83
  }
unsigned int GFWX::unsignedDecode<39>(GFWX::Bits&)
Line
Count
Source
204
75
  {
205
75
    uint32_t x = stream.getZeros(12);
206
75
    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
75
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
75
  }
unsigned int GFWX::unsignedDecode<43>(GFWX::Bits&)
Line
Count
Source
204
75
  {
205
75
    uint32_t x = stream.getZeros(12);
206
75
    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
75
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
75
  }
unsigned int GFWX::unsignedDecode<47>(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<51>(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<55>(GFWX::Bits&)
Line
Count
Source
204
69
  {
205
69
    uint32_t x = stream.getZeros(12);
206
69
    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
69
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
69
  }
unsigned int GFWX::unsignedDecode<59>(GFWX::Bits&)
Line
Count
Source
204
68
  {
205
68
    uint32_t x = stream.getZeros(12);
206
68
    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
68
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
68
  }
unsigned int GFWX::unsignedDecode<63>(GFWX::Bits&)
Line
Count
Source
204
68
  {
205
68
    uint32_t x = stream.getZeros(12);
206
68
    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
68
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
68
  }
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.0k
  {
205
61.0k
    uint32_t x = stream.getZeros(12);
206
61.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
61.0k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
61.0k
  }
unsigned int GFWX::unsignedDecode<8>(GFWX::Bits&)
Line
Count
Source
204
1.72k
  {
205
1.72k
    uint32_t x = stream.getZeros(12);
206
1.72k
    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.72k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.72k
  }
unsigned int GFWX::unsignedDecode<12>(GFWX::Bits&)
Line
Count
Source
204
1.32k
  {
205
1.32k
    uint32_t x = stream.getZeros(12);
206
1.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
1.32k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.32k
  }
unsigned int GFWX::unsignedDecode<16>(GFWX::Bits&)
Line
Count
Source
204
1.17k
  {
205
1.17k
    uint32_t x = stream.getZeros(12);
206
1.17k
    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.17k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.17k
  }
unsigned int GFWX::unsignedDecode<20>(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<24>(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<28>(GFWX::Bits&)
Line
Count
Source
204
1.06k
  {
205
1.06k
    uint32_t x = stream.getZeros(12);
206
1.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
1.06k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.06k
  }
unsigned int GFWX::unsignedDecode<32>(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<36>(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<40>(GFWX::Bits&)
Line
Count
Source
204
1.01k
  {
205
1.01k
    uint32_t x = stream.getZeros(12);
206
1.01k
    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.01k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
1.01k
  }
unsigned int GFWX::unsignedDecode<44>(GFWX::Bits&)
Line
Count
Source
204
986
  {
205
986
    uint32_t x = stream.getZeros(12);
206
986
    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
986
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
986
  }
unsigned int GFWX::unsignedDecode<48>(GFWX::Bits&)
Line
Count
Source
204
968
  {
205
968
    uint32_t x = stream.getZeros(12);
206
968
    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
968
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
968
  }
unsigned int GFWX::unsignedDecode<52>(GFWX::Bits&)
Line
Count
Source
204
946
  {
205
946
    uint32_t x = stream.getZeros(12);
206
946
    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
946
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
946
  }
unsigned int GFWX::unsignedDecode<56>(GFWX::Bits&)
Line
Count
Source
204
938
  {
205
938
    uint32_t x = stream.getZeros(12);
206
938
    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
938
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
938
  }
unsigned int GFWX::unsignedDecode<60>(GFWX::Bits&)
Line
Count
Source
204
926
  {
205
926
    uint32_t x = stream.getZeros(12);
206
926
    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
926
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
926
  }
unsigned int GFWX::unsignedDecode<64>(GFWX::Bits&)
Line
Count
Source
204
924
  {
205
924
    uint32_t x = stream.getZeros(12);
206
924
    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
924
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
924
  }
unsigned int GFWX::unsignedDecode<68>(GFWX::Bits&)
Line
Count
Source
204
909
  {
205
909
    uint32_t x = stream.getZeros(12);
206
909
    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
909
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
909
  }
unsigned int GFWX::unsignedDecode<72>(GFWX::Bits&)
Line
Count
Source
204
831
  {
205
831
    uint32_t x = stream.getZeros(12);
206
831
    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
831
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
831
  }
unsigned int GFWX::unsignedDecode<76>(GFWX::Bits&)
Line
Count
Source
204
826
  {
205
826
    uint32_t x = stream.getZeros(12);
206
826
    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
826
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
826
  }
unsigned int GFWX::unsignedDecode<80>(GFWX::Bits&)
Line
Count
Source
204
821
  {
205
821
    uint32_t x = stream.getZeros(12);
206
821
    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
821
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
821
  }
unsigned int GFWX::unsignedDecode<84>(GFWX::Bits&)
Line
Count
Source
204
806
  {
205
806
    uint32_t x = stream.getZeros(12);
206
806
    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
806
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
806
  }
unsigned int GFWX::unsignedDecode<88>(GFWX::Bits&)
Line
Count
Source
204
793
  {
205
793
    uint32_t x = stream.getZeros(12);
206
793
    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
793
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
793
  }
unsigned int GFWX::unsignedDecode<92>(GFWX::Bits&)
Line
Count
Source
204
788
  {
205
788
    uint32_t x = stream.getZeros(12);
206
788
    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
788
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
788
  }
unsigned int GFWX::unsignedDecode<96>(GFWX::Bits&)
Line
Count
Source
204
770
  {
205
770
    uint32_t x = stream.getZeros(12);
206
770
    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
770
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
770
  }
unsigned int GFWX::unsignedDecode<100>(GFWX::Bits&)
Line
Count
Source
204
768
  {
205
768
    uint32_t x = stream.getZeros(12);
206
768
    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
768
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
768
  }
unsigned int GFWX::unsignedDecode<104>(GFWX::Bits&)
Line
Count
Source
204
750
  {
205
750
    uint32_t x = stream.getZeros(12);
206
750
    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
750
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
750
  }
unsigned int GFWX::unsignedDecode<108>(GFWX::Bits&)
Line
Count
Source
204
711
  {
205
711
    uint32_t x = stream.getZeros(12);
206
711
    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
711
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
711
  }
unsigned int GFWX::unsignedDecode<0>(GFWX::Bits&)
Line
Count
Source
204
54.5k
  {
205
54.5k
    uint32_t x = stream.getZeros(12);
206
54.5k
    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.5k
    return (pot < 108 && x == 12) ? (12 << p) + unsignedDecode<pot < 108 ? pot + 4 : 108>(stream) : p ? (x << p) + stream.getBits(p) : x;
208
54.5k
  }
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
8.07M
  {
212
8.07M
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
8.07M
  }
void GFWX::interleavedCode<0>(int, GFWX::Bits&)
Line
Count
Source
211
2.73M
  {
212
2.73M
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
2.73M
  }
void GFWX::interleavedCode<2>(int, GFWX::Bits&)
Line
Count
Source
211
358k
  {
212
358k
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
358k
  }
void GFWX::interleavedCode<3>(int, GFWX::Bits&)
Line
Count
Source
211
424k
  {
212
424k
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
424k
  }
void GFWX::interleavedCode<4>(int, GFWX::Bits&)
Line
Count
Source
211
632k
  {
212
632k
    unsignedCode<pot>(x <= 0 ? -2 * x : 2 * x - 1, stream);  // interleave positive and negative values
213
632k
  }
214
215
  template<int pot> int interleavedDecode(Bits & stream)
216
130k
  {
217
130k
    int const x = unsignedDecode<pot>(stream);
218
130k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
130k
  }
int GFWX::interleavedDecode<1>(GFWX::Bits&)
Line
Count
Source
216
45.1k
  {
217
45.1k
    int const x = unsignedDecode<pot>(stream);
218
45.1k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
45.1k
  }
int GFWX::interleavedDecode<0>(GFWX::Bits&)
Line
Count
Source
216
54.5k
  {
217
54.5k
    int const x = unsignedDecode<pot>(stream);
218
54.5k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
54.5k
  }
int GFWX::interleavedDecode<2>(GFWX::Bits&)
Line
Count
Source
216
13.8k
  {
217
13.8k
    int const x = unsignedDecode<pot>(stream);
218
13.8k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
13.8k
  }
int GFWX::interleavedDecode<3>(GFWX::Bits&)
Line
Count
Source
216
11.4k
  {
217
11.4k
    int const x = unsignedDecode<pot>(stream);
218
11.4k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
11.4k
  }
int GFWX::interleavedDecode<4>(GFWX::Bits&)
Line
Count
Source
216
4.95k
  {
217
4.95k
    int const x = unsignedDecode<pot>(stream);
218
4.95k
    return (x & 1) ? (x + 1) / 2 : -x / 2;
219
4.95k
  }
220
221
  template<int pot> void signedCode(int x, Bits & stream)
222
12.1M
  {
223
12.1M
    unsignedCode<pot>(abs(x), stream);
224
12.1M
    if (x)
225
10.6M
      stream.putBits(x > 0 ? 1 : 0, 1);
226
12.1M
  }
void GFWX::signedCode<2>(int, GFWX::Bits&)
Line
Count
Source
222
312k
  {
223
312k
    unsignedCode<pot>(abs(x), stream);
224
312k
    if (x)
225
227k
      stream.putBits(x > 0 ? 1 : 0, 1);
226
312k
  }
void GFWX::signedCode<4>(int, GFWX::Bits&)
Line
Count
Source
222
10.8M
  {
223
10.8M
    unsignedCode<pot>(abs(x), stream);
224
10.8M
    if (x)
225
9.77M
      stream.putBits(x > 0 ? 1 : 0, 1);
226
10.8M
  }
void GFWX::signedCode<1>(int, GFWX::Bits&)
Line
Count
Source
222
304k
  {
223
304k
    unsignedCode<pot>(abs(x), stream);
224
304k
    if (x)
225
165k
      stream.putBits(x > 0 ? 1 : 0, 1);
226
304k
  }
void GFWX::signedCode<3>(int, GFWX::Bits&)
Line
Count
Source
222
618k
  {
223
618k
    unsignedCode<pot>(abs(x), stream);
224
618k
    if (x)
225
460k
      stream.putBits(x > 0 ? 1 : 0, 1);
226
618k
  }
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.3k
  {
230
13.3k
    int x = unsignedDecode<pot>(stream);
231
13.3k
    return x ? stream.getBits(1) ? x : -x : 0;
232
13.3k
  }
int GFWX::signedDecode<1>(GFWX::Bits&)
Line
Count
Source
229
4.30k
  {
230
4.30k
    int x = unsignedDecode<pot>(stream);
231
4.30k
    return x ? stream.getBits(1) ? x : -x : 0;
232
4.30k
  }
int GFWX::signedDecode<3>(GFWX::Bits&)
Line
Count
Source
229
8.22k
  {
230
8.22k
    int x = unsignedDecode<pot>(stream);
231
8.22k
    return x ? stream.getBits(1) ? x : -x : 0;
232
8.22k
  }
233
234
  template<typename T> T median(T a, T b, T c)
235
154M
  {
236
154M
    return a < b ? c > b ? b : c < a ? a : c : c > a ? a : c < b ? b : c;
237
154M
  }
238
239
  template<typename T> T roundFraction(T num, T denom)
240
154M
  {
241
154M
    return num < 0 ? (num - denom / 2) / denom : (num + denom / 2) / denom;
242
154M
  }
243
244
  template<typename T> T cubic(T c0, T c1, T c2, T c3)
245
154M
  {
246
154M
    return median(T(roundFraction((-c0 + 9 * (c1 + c2) - c3), 16)), c1, c2);
247
154M
  }
248
249
  template<typename T> void lift(Image<T> & image, int x0, int y0, int x1, int y1, int step, int filter)
250
21.9k
  {
251
21.9k
    int const sizex = x1 - x0;
252
21.9k
    int const sizey = y1 - y0;
253
127k
    while (step < sizex || step < sizey)
254
105k
    {
255
105k
      if (step < sizex)  // horizontal lifting
256
51.2k
      {
257
51.2k
        OMP_PARALLEL_FOR(ThreadIterations)
258
22.6M
        for (int y = 0; y < sizey; y += step)
259
22.5M
        {
260
22.5M
          int x;
261
22.5M
          T * base = &image[y0 + y][x0], * base1 = base - step, * base2 = base + step, * base3 = base + step * 3;
262
22.5M
          if (filter == FilterCubic)
263
13.3M
          {
264
13.3M
            T c0 = *base, c1 = *base, c2 = step * 2 < sizex ? base[step * 2] : *base, c3;
265
28.9M
            for (x = step; x < sizex - step * 3; x += step * 2, c0 = c1, c1 = c2, c2 = c3)
266
15.6M
              base[x] -= cubic(c0, c1, c2, c3 = base3[x]);
267
30.3M
            for (; x < sizex; x += step * 2, c0 = c1, c1 = c2)
268
17.0M
              base[x] -= cubic(c0, c1, c2, c2);
269
13.3M
            T g0 = base[step], g1 = base[step], g2 = step * 3 < sizex ? base[step * 3] : base[step], g3;
270
28.2M
            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
19.6M
            for (; x < sizex; x += step * 2, g0 = g1, g1 = g2)
273
6.34M
              base[x] += cubic(g0, g1, g2, g2) / 2;
274
13.3M
          }
275
9.24M
          else
276
9.24M
          {
277
36.7M
            for (x = step; x < sizex - step; x += step * 2)
278
27.5M
              base[x] -= (base1[x] + base2[x]) / 2;
279
9.24M
            if (x < sizex)
280
7.70M
              base[x] -= base1[x];
281
35.2M
            for (x = step * 2; x < sizex - step; x += step * 2)
282
25.9M
              base[x] += (base1[x] + base2[x]) / 4;
283
9.24M
            if (x < sizex)
284
1.54M
              base[x] += base1[x] / 2;
285
9.24M
          }
286
22.5M
        }
287
51.2k
      }
288
105k
      if (step < sizey)  // vertical lifting
289
74.9k
      {
290
74.9k
        OMP_PARALLEL_FOR(ThreadIterations)
291
71.0M
        for (int y = step; y < sizey; y += step * 2)
292
70.9M
        {
293
70.9M
          T * const base = &image[y0 + y][x0];
294
70.9M
          T const * const c1base = &image[y0 + y - step][x0], * const c2base = y + step < sizey ? &image[y0 + y + step][x0] : c1base;
295
70.9M
          if (filter == FilterCubic)
296
37.9M
          {
297
37.9M
            T const * const c0base = y - step * 3 >= 0 ? &image[y0 + y - step * 3][x0] : c1base;
298
37.9M
            T const * const c3base = y + step * 3 < sizey ? &image[y0 + y + step * 3][x0] : c2base;
299
87.5M
            for (int x = 0; x < sizex; x += step)
300
49.6M
              base[x] -= cubic(c0base[x], c1base[x], c2base[x], c3base[x]);
301
37.9M
          }
302
75.8M
          else for (int x = 0; x < sizex; x += step)
303
42.8M
            base[x] -= (c1base[x] + c2base[x]) / 2;
304
70.9M
        }
305
74.9k
        OMP_PARALLEL_FOR(ThreadIterations)
306
70.9M
        for (int y = step * 2; y < sizey; y += step * 2)
307
70.9M
        {
308
70.9M
          T * const base = &image[y0 + y][x0];
309
70.9M
          T const * const g1base = &image[y0 + y - step][x0], * const g2base = y + step < sizey ? &image[y0 + y + step][x0] : g1base;
310
70.9M
          if (filter == FilterCubic)
311
37.8M
          {
312
37.8M
            T const * const g0base = y - step * 3 >= 0 ? &image[y0 + y - step * 3][x0] : g1base;
313
37.8M
            T const * const g3base = y + step * 3 < sizey ? &image[y0 + y + step * 3][x0] : g2base;
314
86.9M
            for (int x = 0; x < sizex; x += step)
315
49.0M
              base[x] += cubic(g0base[x], g1base[x], g2base[x], g3base[x]) / 2;
316
37.8M
          }
317
74.7M
          else for (int x = 0; x < sizex; x += step)
318
41.7M
            base[x] += (g1base[x] + g2base[x]) / 4;
319
70.9M
        }
320
74.9k
      }
321
105k
      step *= 2;
322
105k
    }
323
21.9k
  }
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
22.5k
  {
406
22.5k
    typedef typename std::conditional<sizeof(T) < 4, int32_t, int64_t>::type aux;
407
22.5k
    int const sizex = x1 - x0;
408
22.5k
    int const sizey = y1 - y0;
409
22.5k
    int skip = step;
410
40.0k
    while (skip < sizex && skip < sizey)
411
18.7k
    {
412
18.7k
      int const q = std::max(std::max(1, minQ), quality);
413
18.7k
      if (q >= maxQ) break;
414
17.5k
      OMP_PARALLEL_FOR(ThreadIterations)
415
21.5M
      for (int y = 0; y < sizey; y += skip)
416
21.5M
      {
417
21.5M
        T * base = &image[y0 + y][x0];
418
21.5M
        int const xStep = (y & skip) ? skip : skip * 2;
419
92.0M
        for (int x = xStep - skip; x < sizex; x += xStep)  // [NOTE] arranged so that (x | y) & skip == 1
420
70.5M
          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
21.5M
      }
422
17.5k
      skip *= 2;
423
17.5k
      quality = std::min(maxQ, quality * 2);  // [MAGIC] This approximates the JPEG 2000 baseline quantizer
424
17.5k
    }
425
22.5k
  }
void GFWX::quantize<short, false>(GFWX::Image<short>&, int, int, int, int, int, int, int, int)
Line
Count
Source
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.7k
    while (skip < sizex && skip < sizey)
411
17.8k
    {
412
17.8k
      int const q = std::max(std::max(1, minQ), quality);
413
17.8k
      if (q >= maxQ) break;
414
16.7k
      OMP_PARALLEL_FOR(ThreadIterations)
415
21.4M
      for (int y = 0; y < sizey; y += skip)
416
21.4M
      {
417
21.4M
        T * base = &image[y0 + y][x0];
418
21.4M
        int const xStep = (y & skip) ? skip : skip * 2;
419
89.2M
        for (int x = xStep - skip; x < sizex; x += xStep)  // [NOTE] arranged so that (x | y) & skip == 1
420
67.7M
          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
21.4M
      }
422
16.7k
      skip *= 2;
423
16.7k
      quality = std::min(maxQ, quality * 2);  // [MAGIC] This approximates the JPEG 2000 baseline quantizer
424
16.7k
    }
425
21.9k
  }
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
49.8M
  {
429
49.8M
    return t * t;
430
49.8M
  }
431
432
  inline void addContext(int x, int w, uint32_t & sum, uint32_t & sum2, uint32_t & count)
433
28.2M
  {
434
28.2M
    sum += uint32_t(x = abs(x)) * w;
435
28.2M
    sum2 += square(std::min(uint32_t(x), 4096u)) * w; // [MAGIC] avoid overflow in last line of getContext
436
28.2M
    count += w;
437
28.2M
  }
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
12.3M
  {
441
12.3M
    int px = x0 + (x & ~(skip * 2)) + (x & skip);
442
12.3M
    if (px >= x1)
443
927k
      px -= skip * 2;
444
12.3M
    int py = y0 + (y & ~(skip * 2)) + (y & skip);
445
12.3M
    if (py >= y1)
446
681k
      py -= skip * 2;
447
12.3M
    uint32_t count = 0, sum = 0, sum2 = 0;
448
12.3M
    addContext(abs(image[py][px]), 2, sum, sum2, count);  // ancestor
449
12.3M
    if ((y & skip) && (x | skip) < x1 - x0)
450
3.05M
    {
451
3.05M
      addContext(image[y0 + y - skip][x0 + (x | skip)], 2, sum, sum2, count); // upper sibling
452
3.05M
      if (x & skip)
453
1.52M
        addContext(image[y0 + y][x0 + x - skip], 2, sum, sum2, count); // left sibling
454
3.05M
    }
455
12.3M
    if (y >= skip * 2 && x >= skip * 2)  // neighbors
456
1.83M
    {
457
1.83M
      addContext(image[y0 + y - skip * 2][x0 + x], 4, sum, sum2, count);
458
1.83M
      addContext(image[y0 + y][x0 + x - skip * 2], 4, sum, sum2, count);
459
1.83M
      addContext(image[y0 + y - skip * 2][x0 + x - skip * 2], 2, sum, sum2, count);
460
1.83M
      if (x + skip * 2 < x1 - x0)
461
1.61M
        addContext(image[y0 + y - skip * 2][x0 + x + skip * 2], 2, sum, sum2, count);
462
1.83M
      if (y >= skip * 4 && x >= skip * 4)
463
1.10M
      {
464
1.10M
        addContext(image[y0 + y - skip * 4][x0 + x], 2, sum, sum2, count);
465
1.10M
        addContext(image[y0 + y][x0 + x - skip * 4], 2, sum, sum2, count);
466
1.10M
        addContext(image[y0 + y - skip * 4][x0 + x - skip * 4], 1, sum, sum2, count);
467
1.10M
        if (x + skip * 4 < x1 - x0)
468
914k
          addContext(image[y0 + y - skip * 4][x0 + x + skip * 4], 1, sum, sum2, count);
469
1.10M
      }
470
1.83M
    }
471
12.3M
    return std::make_pair((sum * 16u + count / 2u) / count, (sum2 * 16u + count / 2u) / count); // set sums relative to 16 count
472
12.3M
  }
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.32M
  {
476
8.32M
    int const sizex = x1 - x0;
477
8.32M
    int const sizey = y1 - y0;
478
8.32M
    if (hasDC && sizex > 0 && sizey > 0)
479
15.1k
      signedCode<4>(image[y0][x0], stream);
480
8.32M
    std::pair<uint32_t, uint32_t> context(0, 0);
481
8.32M
    int run = 0, runCoder = (scheme == EncoderTurbo ? (!q || (step < 2048 && q * step < 2048)) ? 1 : 0 : 0);  // avoid overflow checking q * step < 2048
482
99.7M
    for (int y = 0; y < sizey; y += step)
483
91.4M
    {
484
91.4M
      T * base = &image[y0 + y][x0];
485
91.4M
      int const xStep = (y & step) ? step : step * 2;
486
185M
      for (int x = xStep - step; x < sizex; x += xStep)  // [NOTE] arranged so that (x | y) & step == 1
487
94.3M
      {
488
94.3M
        T s = base[x];
489
94.3M
        if (runCoder && !s)  // run
490
70.0M
          ++ run;
491
24.3M
        else
492
24.3M
        {
493
24.3M
          if (scheme == EncoderTurbo)
494
7.48M
          {
495
7.48M
            if (runCoder)  // break the run
496
4.39M
            {
497
4.39M
              unsignedCode<1>(run, stream);
498
4.39M
              run = 0;
499
4.39M
              interleavedCode<1>(s < 0 ? s + 1 : s, stream);  // s can't be zero, so shift negatives by 1
500
4.39M
            }
501
3.08M
            else
502
3.08M
              interleavedCode<1>(s, stream);
503
7.48M
            continue;
504
7.48M
          }
505
16.8M
          if (runCoder)  // break the run
506
380k
          {
507
380k
            runCoder == 1 ? unsignedCode<1>(run, stream) : runCoder == 2 ? unsignedCode<2>(run, stream)
508
282k
              : runCoder == 3 ? unsignedCode<3>(run, stream) : unsignedCode<4>(run, stream);
509
380k
            run = 0;
510
380k
            if (s < 0)
511
191k
              ++ s; // s can't be zero, so shift negatives by 1
512
380k
          }
513
16.8M
          if (scheme == EncoderContextual)
514
12.2M
            context = getContext(image, x0, y0, x1, y1, x, y, step);
515
16.8M
          uint32_t const sumSq = square(context.first);
516
16.8M
          if (sumSq < 2u * context.second + (isChroma ? 250u : 100u))
517
2.73M
            interleavedCode<0>(s, stream);
518
14.1M
          else if (sumSq < 2u * context.second + 950u)
519
590k
            interleavedCode<1>(s, stream);
520
13.5M
          else if (sumSq < 3u * context.second + 3000u)
521
663k
          {
522
663k
            if (sumSq < 5u * context.second + 400u)
523
304k
              signedCode<1>(s, stream);
524
358k
            else
525
358k
              interleavedCode<2>(s, stream);
526
663k
          }
527
12.8M
          else if (sumSq < 3u * context.second + 12000u)
528
716k
          {
529
716k
            if (sumSq < 5u * context.second + 3000u)
530
292k
              signedCode<2>(s, stream);
531
424k
            else
532
424k
              interleavedCode<3>(s, stream);
533
716k
          }
534
12.1M
          else if (sumSq < 4u * context.second + 44000u)
535
1.25M
          {
536
1.25M
            if (sumSq < 6u * context.second + 12000u)
537
618k
              signedCode<3>(s, stream);
538
632k
            else
539
632k
              interleavedCode<4>(s, stream);
540
1.25M
          }
541
10.8M
          else
542
10.8M
            signedCode<4>(s, stream);
543
16.8M
          if (scheme == EncoderFast)  // use decaying first and second moment
544
4.61M
          {
545
4.61M
            uint32_t const t = abs(s);
546
4.61M
            context = std::make_pair(((context.first * 15u + 7u) >> 4) + t, ((context.second * 15u + 7u) >> 4) + square(std::min(t, 4096u)));
547
4.61M
            if (!s == !runCoder)
548
1.99M
              runCoder = context.first < 1 ? 4 : context.first < 2 ? 3 : context.first < 4 ? 2 : context.first < 8 ? 1 : 0;
549
4.61M
          }
550
12.2M
          else if (!s == !runCoder)
551
2.17M
            runCoder = q == 1024 ? context.first < 2u ? 1 : 0 : (context.first < 4u && context.second < 2u) ? 4 : (context.first < 8u
552
1.64M
            && context.second < 4u) ? 3 : (2u * sumSq < 3u * context.second + 48u) ? 2 : (2u * sumSq < 5u * context.second + 32u) ? 1 : 0;
553
16.8M
        }
554
94.3M
      }
555
91.4M
    }
556
8.32M
    if (run)  // flush run
557
1.53M
      runCoder == 1 ? unsignedCode<1>(run, stream) : runCoder == 2 ? unsignedCode<2>(run, stream)
558
300k
        : runCoder == 3 ? unsignedCode<3>(run, stream) : unsignedCode<4>(run, stream);
559
8.32M
  }
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
41
  {
563
41
    int const sizex = x1 - x0;
564
41
    int const sizey = y1 - y0;
565
41
    if (hasDC && sizex > 0 && sizey > 0)
566
4
      image[y0][x0] = signedDecode<4>(stream);
567
41
    std::pair<uint32_t, uint32_t> context(0, 0);
568
41
    int run = -1, runCoder = (scheme == EncoderTurbo ? (!q || (step < 2048 && q * step < 2048)) ? 1 : 0 : 0);  // avoid overflow checking q * step < 2048
569
750
    for (int y = 0; y < sizey; y += step)
570
709
    {
571
709
      T * base = &image[y0 + y][x0];
572
709
      int const xStep = (y & step) ? step : step * 2;
573
499k
      for (int x = xStep - step; x < sizex; x += xStep)  // [NOTE] arranged so that (x | y) & step == 1
574
499k
      {
575
499k
        T s = 0;
576
499k
        if (runCoder && run == -1)
577
50.1k
          run = runCoder == 1 ? unsignedDecode<1>(stream) : runCoder == 2 ? unsignedDecode<2>(stream)
578
48.5k
            : runCoder == 3 ? unsignedDecode<3>(stream) : unsignedDecode<4>(stream);
579
499k
        if (run > 0)
580
336k
          -- run;  // consume a zero
581
162k
        else
582
162k
        {
583
162k
          if (scheme == EncoderTurbo)
584
16.3k
            s = interleavedDecode<1>(stream);
585
145k
          else
586
145k
          {
587
145k
            if (scheme == EncoderContextual)
588
145k
              context = getContext(image, x0, y0, x1, y1, x, y, step);
589
145k
            uint32_t const sumSq = square(context.first);
590
145k
            if (sumSq < 2u * context.second + (isChroma ? 250u : 100u))
591
54.5k
              s = interleavedDecode<0>(stream);
592
91.2k
            else if (sumSq < 2u * context.second + 950u)
593
28.7k
              s = interleavedDecode<1>(stream);
594
62.4k
            else if (sumSq < 3u * context.second + 3000u)
595
18.2k
            {
596
18.2k
              if (sumSq < 5u * context.second + 400u)
597
4.30k
                s = signedDecode<1>(stream);
598
13.8k
              else
599
13.8k
                s = interleavedDecode<2>(stream);
600
18.2k
            }
601
44.2k
            else if (sumSq < 3u * context.second + 12000u)
602
17.7k
            {
603
17.7k
              if (sumSq < 5u * context.second + 3000u)
604
6.29k
                s = signedDecode<2>(stream);
605
11.4k
              else
606
11.4k
                s = interleavedDecode<3>(stream);
607
17.7k
            }
608
26.5k
            else if (sumSq < 4u * context.second + 44000u)
609
13.1k
            {
610
13.1k
              if (sumSq < 6u * context.second + 12000u)
611
8.22k
                s = signedDecode<3>(stream);
612
4.95k
              else
613
4.95k
                s = interleavedDecode<4>(stream);
614
13.1k
            }
615
13.3k
            else
616
13.3k
              s = signedDecode<4>(stream);
617
145k
            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
145k
            else if (!s == !runCoder)
625
17.2k
              runCoder = q == 1024 ? context.first < 2u ? 1 : 0 : (context.first < 4u && context.second < 2u) ? 4 : (context.first < 8u
626
13.8k
              && context.second < 4u) ? 3 : (2u * sumSq < 3u * context.second + 48u) ? 2 : (2u * sumSq < 5u * context.second + 32u) ? 1 : 0;
627
145k
          }
628
162k
          if (run == 0 && s <= 0)
629
7.37k
            -- s; // s can't be zero, so shift negatives by 1
630
162k
          run = -1;
631
162k
        }
632
499k
        base[x] = s;
633
499k
      }
634
709
    }
635
41
  }
636
637
  template<typename T> void shiftVector(T * data, int shift, int count)
638
1.22k
  {
639
1.22k
    OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
640
35.3M
    for (int i = 0; i < count; ++ i)
641
35.3M
      data[i] >>= shift;
642
1.22k
  }
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.97G
          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
341
      shiftVector(destination, 1, bufferSize);
670
709k
    else if (denom == 4)
671
634
      shiftVector(destination, 2, bufferSize);
672
708k
    else if (denom == 8)
673
246
      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.41k
  {
647
5.88k
    while (*pc >= 0)
648
3.47k
    {
649
3.47k
      int const c = *(pc ++);
650
3.47k
      A const factor = *(pc ++);
651
3.47k
      if (isChroma[c] == -1)
652
1.61k
      {
653
1.61k
        auto layer = imageData + ((c / header.channels) * bufferSize * header.channels + c % header.channels);
654
1.61k
        A const boostFactor = boost * factor;
655
1.61k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
656
41.1M
        for (int i = 0; i < bufferSize; ++ i)
657
41.1M
          destination[i] += layer[i * header.channels] * boostFactor;
658
1.61k
      }
659
1.85k
      else
660
1.85k
      {
661
1.85k
        A const * auxDataC = auxData + c * bufferSize;
662
1.85k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
663
54.7M
        for (int i = 0; i < bufferSize; ++ i)
664
54.7M
          destination[i] += auxDataC[i] * factor;
665
1.85k
      }
666
3.47k
    }
667
2.41k
    A const denom = *((++ pc) ++);
668
2.41k
    if (denom == 2)
669
246
      shiftVector(destination, 1, bufferSize);
670
2.17k
    else if (denom == 4)
671
560
      shiftVector(destination, 2, bufferSize);
672
1.61k
    else if (denom == 8)
673
246
      shiftVector(destination, 3, bufferSize);
674
1.36k
    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.41k
  }
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.25k
  #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.25k
  #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.25k
  #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
3.02k
  {
691
3.02k
    typedef typename std::remove_reference<decltype(imageData[0])>::type base;
692
3.02k
    typedef typename std::conditional<sizeof(base) < 2, int16_t, int32_t>::type aux;
693
3.02k
    if (header.sizex > (1 << 30) || header.sizey > (1 << 30))  // [NOTE] current implementation can't go over 2^30
694
0
      return ErrorMalformed;
695
3.02k
    Bits stream(reinterpret_cast<uint32_t *>(buffer), reinterpret_cast<uint32_t *>(buffer) + size / 4);
696
3.02k
    stream.putBits('G' | ('F' << 8) | ('W' << 16) | ('X' << 24), 32);
697
3.02k
    stream.putBits(header.version = 1, 32);
698
3.02k
    stream.putBits(header.sizex, 32);
699
3.02k
    stream.putBits(header.sizey, 32);
700
3.02k
    stream.putBits(header.layers - 1, 16);
701
3.02k
    stream.putBits(header.channels - 1, 16);
702
3.02k
    stream.putBits((header.bitDepth ? header.bitDepth : (header.bitDepth = std::numeric_limits<base>::digits)) - 1, 8);
703
3.02k
    stream.putBits(header.isSigned = std::numeric_limits<base>::is_signed ? 1 : 0, 1);
704
3.02k
    stream.putBits(header.quality - 1, 10);
705
3.02k
    stream.putBits(header.chromaScale - 1, 8);
706
3.02k
    stream.putBits(header.blockSize - 2, 5);
707
3.02k
    stream.putBits(header.filter, 8);
708
3.02k
    stream.putBits(header.quantization, 8);
709
3.02k
    stream.putBits(header.encoder, 8);
710
3.02k
    stream.putBits(header.intent, 8);
711
3.02k
    stream.putBits(int(metaDataSize / 4), 32);
712
3.02k
    stream.buffer = std::copy(reinterpret_cast<uint32_t *>(metaData), reinterpret_cast<uint32_t *>(metaData) + metaDataSize / 4, stream.buffer);
713
3.02k
    int const bufferSize = header.sizex * header.sizey;
714
3.02k
    std::vector<aux> auxData((size_t)header.layers * header.channels * bufferSize, 0);
715
3.02k
    std::vector<int> isChroma(header.layers * header.channels, -1);
716
3.02k
    int const chromaQuality = std::max(1, (header.quality + header.chromaScale / 2) / header.chromaScale);
717
3.02k
    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
3.02k
    if (channelTransform)  // run color transform program (and also encode it to the file)
719
806
    {
720
806
      int const * pc = channelTransform;
721
3.22k
      while (*pc >= 0)
722
2.41k
      {
723
2.41k
        int const c = *(pc ++);
724
2.41k
        aux * destination = &auxData[c * bufferSize];
725
2.41k
        transformTerm(pc, destination, &auxData[0], bufferSize, imageData, header, isChroma, boost);
726
2.41k
        auto layer = imageData + ((c / header.channels) * bufferSize * header.channels + c % header.channels);
727
2.41k
        OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
728
61.7M
        for (int i = 0; i < bufferSize; ++ i)
729
61.7M
          destination[i] += layer[i * header.channels] * boost;
730
2.41k
        isChroma[c] = *(pc ++);
731
2.41k
      }
732
18.2k
      for (int const * i = channelTransform; i <= pc; ++ i)
733
17.4k
        signedCode<2>(*i, stream);
734
806
    }
735
2.21k
    else
736
2.21k
      signedCode<2>(-1, stream);
737
3.02k
    stream.flushWriteWord();
738
12.1k
    for (int c = 0; c < header.layers * header.channels; ++ c) if (isChroma[c] == -1)  // copy channels having no transform
739
6.65k
    {
740
6.65k
      aux * destination = &auxData[c * bufferSize];
741
6.65k
      auto layer = imageData + ((c / header.channels) * bufferSize * header.channels + c % header.channels);
742
6.65k
      OMP_PARALLEL_FOR(ThreadIterations * ThreadIterations)
743
60.3M
      for (int i = 0; i < bufferSize; ++ i)
744
60.3M
        destination[i] = layer[i * header.channels] * boost;
745
6.65k
      isChroma[c] = 0;
746
6.65k
    }
747
12.1k
    for (int c = 0; c < header.layers * header.channels; ++ c)  // lift and quantize the channels
748
9.07k
    {
749
9.07k
      Image<aux> auxImage(&auxData[c * bufferSize], header.sizex, header.sizey);
750
9.07k
      lift(auxImage, 0, 0, header.sizex, header.sizey, 1, header.filter);
751
9.07k
      if (header.intent >= IntentBayerRGGB && header.intent <= IntentBayerGeneric)
752
4.30k
      {
753
21.5k
        for (int ox = 0; ox <= 1; ++ ox) for (int oy = 1 - ox; oy <= 1; ++ oy)
754
12.9k
          lift(auxImage, ox, oy, header.sizex, header.sizey, 2, header.filter);
755
25.8k
        for (int ox = 0; ox <= 1; ++ ox) for (int oy = 0; oy <= 1; ++ oy)
756
17.2k
          quantize<aux, false>(auxImage, ox, oy, header.sizex, header.sizey, 2,
757
17.2k
            (ox | oy) ? chromaQuality : header.quality, header.quality, QualityMax * boost);
758
4.30k
      }
759
4.76k
      else
760
4.76k
        quantize<aux, false>(auxImage, 0, 0, header.sizex, header.sizey, 1, isChroma[c] ? chromaQuality : header.quality, 0, QualityMax * boost);
761
9.07k
    }
762
3.02k
    int step = 1;
763
16.8k
    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.1k
    {
767
13.1k
      int64_t const bs = int64_t(step) << header.blockSize;
768
13.1k
      int const blockCountX = (header.sizex + bs - 1) / bs;
769
13.1k
      int const blockCountY = (header.sizey + bs - 1) / bs;
770
13.1k
      int const blockCount = blockCountX * blockCountY * header.layers * header.channels;
771
13.1k
      std::vector<Bits> streamBlock(blockCount, Bits(0, 0));
772
13.1k
      uint32_t * blockBegin = stream.buffer + blockCount; // leave space for block sizes
773
13.1k
      if (blockBegin >= stream.bufferEnd)
774
687
        return ErrorOverflow;
775
3.51M
      for (int block = 0; block < blockCount; ++ block)  // partition buffer into temporary regions for each block
776
3.50M
        streamBlock[block].buffer = blockBegin + (stream.bufferEnd - blockBegin) * block / blockCount;
777
3.51M
      for (int block = 0; block < blockCount; ++ block)
778
3.50M
        streamBlock[block].bufferEnd = block + 1 < blockCount ? streamBlock[block + 1].buffer : stream.bufferEnd;
779
12.4k
      OMP_PARALLEL_FOR(4) // [MAGIC] for some reason, 4 is by far the best option here
780
3.51M
      for (int block = 0; block < blockCount; ++ block)
781
3.50M
      {
782
3.50M
        int const bx = block % blockCountX, by = (block / blockCountX) % blockCountY, c = block / (blockCountX * blockCountY);
783
3.50M
        Image<aux> auxImage(&auxData[c * bufferSize], header.sizex, header.sizey);
784
3.50M
        if (header.intent < IntentBayerRGGB || header.intent > IntentBayerGeneric)
785
1.90M
          encode(auxImage, streamBlock[block], bx * bs, by * bs,
786
1.90M
          int(std::min((bx + 1) * bs, int64_t(header.sizex))), int(std::min((by + 1) * bs, int64_t(header.sizey))),
787
1.90M
          step, header.encoder, isChroma[c] ? chromaQuality : header.quality, hasDC && !bx && !by, isChroma[c] != 0);
788
9.63M
        else for (int ox = 0; ox <= 1; ++ ox) for (int oy = 0; oy <= 1; ++ oy)
789
6.42M
          encode(auxImage, streamBlock[block], bx * bs + ox, by * bs + oy,
790
6.42M
          int(std::min((bx + 1) * bs, int64_t(header.sizex))), int(std::min((by + 1) * bs, int64_t(header.sizey))),
791
6.42M
          2 * step, header.encoder, (ox || oy) ? chromaQuality : header.quality, hasDC && !bx && !by, ox || oy);
792
3.50M
        streamBlock[block].flushWriteWord();
793
3.50M
      }
794
2.17M
      for (int block = 0; block < blockCount; ++ block)  // check streamBlocks for overflow
795
2.16M
        if (streamBlock[block].indexBits < 0)
796
2.05k
          return ErrorOverflow;
797
2.15M
      for (int block = 0; block < blockCount; ++ block)  // encode block lengths [NOTE] this 32-bit encoding limits the file size to < 16 GB
798
2.14M
        *(stream.buffer ++) = uint32_t(streamBlock[block].buffer - (block ? streamBlock[block - 1].bufferEnd : blockBegin));
799
2.15M
      for (int block = 0; block < blockCount; ++ block)  // pack the streamBlock data tightly, by word [NOTE] first block is already packed
800
2.14M
        stream.buffer = block ? std::copy(streamBlock[block - 1].bufferEnd, streamBlock[block].buffer, stream.buffer) : streamBlock[0].buffer;
801
10.4k
      step /= 2;
802
10.4k
    }
803
284
    return reinterpret_cast<uint8_t *>(stream.buffer) - buffer; // return size in bytes
804
3.02k
  }
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
26
  {
808
26
    typedef typename std::remove_reference<decltype(imageData[0])>::type base;
809
26
    typedef typename std::conditional<sizeof(base) < 2, int16_t, int32_t>::type aux;
810
26
    Bits stream(reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(data)), reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(data)) + size / 4);
811
26
    if (size < 28)  // at least load the header
812
0
      return 28;
813
26
    if (stream.getBits(32) != uint32_t('G' | ('F' << 8) | ('W' << 16) | ('X' << 24)))
814
3
      return ErrorMalformed;
815
23
    header.version = stream.getBits(32);
816
23
    header.sizex = stream.getBits(32);
817
23
    header.sizey = stream.getBits(32);
818
23
    header.layers = stream.getBits(16) + 1;
819
23
    header.channels = stream.getBits(16) + 1;
820
23
    header.bitDepth = stream.getBits(8) + 1;
821
23
    header.isSigned = stream.getBits(1);
822
23
    header.quality = stream.getBits(10) + 1;
823
23
    header.chromaScale = stream.getBits(8) + 1;
824
23
    header.blockSize = stream.getBits(5) + 2;
825
23
    header.filter = stream.getBits(8);
826
23
    header.quantization = stream.getBits(8);
827
23
    header.encoder = stream.getBits(8);
828
23
    header.intent = stream.getBits(8);
829
23
    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
22
    if (!imageData)    // just header
832
11
      return ResultOk;
833
11
    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
11
    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
11
    int const sizexDown = (header.sizex + (1 << downsampling) - 1) >> downsampling, sizeyDown = (header.sizey + (1 << downsampling) - 1) >> downsampling;
839
11
    int const bufferSize = sizexDown * sizeyDown;
840
11
    std::vector<aux> auxData((size_t)header.layers * header.channels * bufferSize, 0);
841
11
    std::vector<int> isChroma(header.layers * header.channels, 0), transformProgram, transformSteps;
842
11
    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
11
        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
11
    stream.flushReadWord();
867
11
    int const chromaQuality = std::max(1, (header.quality + header.chromaScale / 2) / header.chromaScale);
868
11
    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
11
    bool isTruncated = false;
870
11
    int step = 1;
871
101
    while (step * 2 < header.sizex || step * 2 < header.sizey)
872
90
      step *= 2;
873
53
    for (bool hasDC = true; (step >> downsampling) >= 1; hasDC = false)  // decode just enough coefficients for downsampled image
874
51
    {
875
51
      int64_t const bs = int64_t(step) << header.blockSize;
876
51
      int const blockCountX = int((header.sizex + bs - 1) / bs);
877
51
      int const blockCountY = int((header.sizey + bs - 1) / bs);
878
51
      int const blockCount = blockCountX * blockCountY * header.layers * header.channels;
879
51
      isTruncated = true;
880
51
      if (stream.buffer + 1 + blockCount > stream.bufferEnd)  // check for enough buffer to read block sizes
881
7
        break;
882
44
      std::vector<Bits> streamBlock(blockCount, Bits(0, 0));
883
182
      for (int block = 0; block < blockCount; ++ block)  // first, read sizes into bufferEnd pointers
884
138
        streamBlock[block].bufferEnd = static_cast<uint32_t *>(0) + *(stream.buffer ++);
885
182
      for (int block = 0; block < blockCount; ++ block)  // then convert sizes to true buffer pointers
886
138
        streamBlock[block].bufferEnd = (streamBlock[block].buffer = block ? streamBlock[block - 1].bufferEnd : stream.buffer)
887
138
                        + (streamBlock[block].bufferEnd - static_cast<uint32_t *>(0));
888
44
      stream.buffer = streamBlock[blockCount - 1].bufferEnd;
889
44
      nextPointOfInterest = reinterpret_cast<uint8_t *>(stream.buffer + ((step >> downsampling) > 1 ? blockCount * 4 : 0)) - data;
890
44
      if (stream.buffer <= stream.bufferEnd)
891
41
        isTruncated = false;
892
44
      int const stepDown = step >> downsampling;
893
44
      int64_t const bsDown = int64_t(stepDown) << header.blockSize;
894
44
      OMP_PARALLEL_FOR(4) // [MAGIC] for some reason, 4 is by far the best option here
895
182
      for (int block = 0; block < blockCount; ++ block) if (!test && streamBlock[block].bufferEnd <= stream.bufferEnd)
896
41
      {
897
41
        int const bx = block % blockCountX, by = (block / blockCountX) % blockCountY, c = block / (blockCountX * blockCountY);
898
41
        Image<aux> auxImage(&auxData[c * bufferSize], sizexDown, sizeyDown);
899
41
        if (header.intent < IntentBayerRGGB || header.intent > IntentBayerGeneric)
900
41
          decode(auxImage, streamBlock[block], int(bx * bsDown), int(by * bsDown),
901
41
          int(std::min((bx + 1) * bsDown, int64_t(sizexDown))), int(std::min((by + 1) * bsDown, int64_t(sizeyDown))),
902
41
          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
41
      }
908
180
      for (int block = 0; block < blockCount; ++ block)  // check if any blocks ran out of buffer, which should not happen on valid files
909
138
        if (streamBlock[block].indexBits < 0)
910
2
          return ErrorMalformed;
911
42
      step /= 2;
912
42
    }
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
}