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  |  | }  |