Coverage Report

Created: 2025-10-13 06:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brunsli/c/common/platform.h
Line
Count
Source
1
// Copyright (c) Google LLC 2019
2
//
3
// Use of this source code is governed by an MIT-style
4
// license that can be found in the LICENSE file or at
5
// https://opensource.org/licenses/MIT.
6
7
/* Macros for compiler / platform specific features and build options.
8
9
   Build options are:
10
    * BRUNSLI_BUILD_32_BIT disables 64-bit optimizations
11
    * BRUNSLI_BUILD_64_BIT forces to use 64-bit optimizations
12
    * BRUNSLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
13
    * BRUNSLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
14
    * BRUNSLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
15
    * BRUNSLI_DEBUG enables "asserts" and extensive logging
16
    * BRUNSLI_DISABLE_LOG disables logging (useful for fuzzing)
17
*/
18
19
#ifndef BRUNSLI_COMMON_PLATFORM_H_
20
#define BRUNSLI_COMMON_PLATFORM_H_
21
22
#include <cstring>  /* memcpy */
23
#include <iomanip>
24
#include <ios>
25
#include <iostream>
26
#include <vector>
27
28
// Implicitly enable BRUNSLI_DEBUG when sanitizers are on.
29
#if !defined(BRUNSLI_DEBUG) && (BRUNSLI_SANITIZED || !defined(NDEBUG))
30
#define BRUNSLI_DEBUG 1
31
#endif
32
33
#if defined(BRUNSLI_USE_LOGGING)
34
#include "base/logging.h"
35
#else  // defined(BRUNSLI_USE_LOGGING)
36
#include <stdio.h>
37
#endif  // defined(BRUNSLI_USE_LOGGING)
38
39
#include "./port.h"
40
#include <brunsli/types.h>
41
42
#if defined(OS_LINUX) || defined(OS_CYGWIN)
43
#include <endian.h>
44
#elif defined(OS_FREEBSD)
45
#include <machine/endian.h>
46
#elif defined(OS_MACOSX)
47
#include <machine/endian.h>
48
/* Let's try and follow the Linux convention */
49
#define BRUNSLI_X_BYTE_ORDER BYTE_ORDER
50
#define BRUNSLI_X_LITTLE_ENDIAN LITTLE_ENDIAN
51
#define BRUNSLI_X_BIG_ENDIAN BIG_ENDIAN
52
#endif
53
54
/* The following macros were borrowed from https://github.com/nemequ/hedley
55
 * with permission of original author - Evan Nemerson <evan@nemerson.com> */
56
57
/* >>> >>> >>> hedley macros */
58
59
/* Define "BRUNSLI_PREDICT_TRUE" and "BRUNSLI_PREDICT_FALSE" macros for capable
60
   compilers.
61
62
To apply compiler hint, enclose the branching condition into macros, like this:
63
64
  if (BRUNSLI_PREDICT_TRUE(zero == 0)) {
65
    // main execution path
66
  } else {
67
    // compiler should place this code outside of main execution path
68
  }
69
70
OR:
71
72
  if (BRUNSLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) {
73
    // compiler should place this code outside of main execution path
74
  }
75
76
*/
77
#if BRUNSLI_GNUC_HAS_BUILTIN(__builtin_expect, 3, 0, 0) || \
78
    BRUNSLI_INTEL_VERSION_CHECK(16, 0, 0) ||               \
79
    BRUNSLI_SUNPRO_VERSION_CHECK(5, 12, 0) ||              \
80
    BRUNSLI_ARM_VERSION_CHECK(4, 1, 0) ||                  \
81
    BRUNSLI_IBM_VERSION_CHECK(10, 1, 0) ||                 \
82
    BRUNSLI_TI_VERSION_CHECK(7, 3, 0) ||                   \
83
    BRUNSLI_TINYC_VERSION_CHECK(0, 9, 27)
84
#define BRUNSLI_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
85
54.1M
#define BRUNSLI_PREDICT_FALSE(x) (__builtin_expect(x, 0))
86
#else
87
#define BRUNSLI_PREDICT_FALSE(x) (x)
88
#define BRUNSLI_PREDICT_TRUE(x) (x)
89
#endif
90
91
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
92
    !defined(__cplusplus)
93
#define BRUNSLI_RESTRICT restrict
94
#elif BRUNSLI_GNUC_VERSION_CHECK(3, 1, 0) ||                         \
95
    BRUNSLI_MSVC_VERSION_CHECK(14, 0, 0) ||                          \
96
    BRUNSLI_INTEL_VERSION_CHECK(16, 0, 0) ||                         \
97
    BRUNSLI_ARM_VERSION_CHECK(4, 1, 0) ||                            \
98
    BRUNSLI_IBM_VERSION_CHECK(10, 1, 0) ||                           \
99
    BRUNSLI_PGI_VERSION_CHECK(17, 10, 0) ||                          \
100
    BRUNSLI_TI_VERSION_CHECK(8, 0, 0) ||                             \
101
    BRUNSLI_IAR_VERSION_CHECK(8, 0, 0) ||                            \
102
    (BRUNSLI_SUNPRO_VERSION_CHECK(5, 14, 0) && defined(__cplusplus))
103
#define BRUNSLI_RESTRICT __restrict
104
#elif BRUNSLI_SUNPRO_VERSION_CHECK(5, 3, 0) && !defined(__cplusplus)
105
#define BRUNSLI_RESTRICT _Restrict
106
#else
107
#define BRUNSLI_RESTRICT
108
#endif
109
110
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
111
    (defined(__cplusplus) && (__cplusplus >= 199711L))
112
#define BRUNSLI_MAYBE_INLINE inline
113
#elif defined(__GNUC_STDC_INLINE__) || defined(__GNUC_GNU_INLINE__) || \
114
    BRUNSLI_ARM_VERSION_CHECK(6, 2, 0)
115
#define BRUNSLI_MAYBE_INLINE __inline__
116
#elif BRUNSLI_MSVC_VERSION_CHECK(12, 0, 0) || \
117
    BRUNSLI_ARM_VERSION_CHECK(4, 1, 0) || BRUNSLI_TI_VERSION_CHECK(8, 0, 0)
118
#define BRUNSLI_MAYBE_INLINE __inline
119
#else
120
#define BRUNSLI_MAYBE_INLINE
121
#endif
122
123
#if BRUNSLI_GNUC_HAS_ATTRIBUTE(always_inline, 4, 0, 0) ||                      \
124
    BRUNSLI_INTEL_VERSION_CHECK(16, 0, 0) ||                                   \
125
    BRUNSLI_SUNPRO_VERSION_CHECK(5, 11, 0) ||                                  \
126
    BRUNSLI_ARM_VERSION_CHECK(4, 1, 0) ||                                      \
127
    BRUNSLI_IBM_VERSION_CHECK(10, 1, 0) ||                                     \
128
    BRUNSLI_TI_VERSION_CHECK(8, 0, 0) ||                                       \
129
    (BRUNSLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
130
#define BRUNSLI_INLINE BRUNSLI_MAYBE_INLINE __attribute__((__always_inline__))
131
#elif BRUNSLI_MSVC_VERSION_CHECK(12, 0, 0)
132
#define BRUNSLI_INLINE BRUNSLI_MAYBE_INLINE __forceinline
133
#elif BRUNSLI_TI_VERSION_CHECK(7, 0, 0) && defined(__cplusplus)
134
#define BRUNSLI_INLINE BRUNSLI_MAYBE_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
135
#elif BRUNSLI_IAR_VERSION_CHECK(8, 0, 0)
136
#define BRUNSLI_INLINE BRUNSLI_MAYBE_INLINE _Pragma("inline=forced")
137
#else
138
#define BRUNSLI_INLINE BRUNSLI_MAYBE_INLINE
139
#endif
140
141
#if BRUNSLI_GNUC_HAS_ATTRIBUTE(noinline, 4, 0, 0) ||                           \
142
    BRUNSLI_INTEL_VERSION_CHECK(16, 0, 0) ||                                   \
143
    BRUNSLI_SUNPRO_VERSION_CHECK(5, 11, 0) ||                                  \
144
    BRUNSLI_ARM_VERSION_CHECK(4, 1, 0) ||                                      \
145
    BRUNSLI_IBM_VERSION_CHECK(10, 1, 0) ||                                     \
146
    BRUNSLI_TI_VERSION_CHECK(8, 0, 0) ||                                       \
147
    (BRUNSLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
148
#define BRUNSLI_NOINLINE __attribute__((__noinline__))
149
#elif BRUNSLI_MSVC_VERSION_CHECK(13, 10, 0)
150
#define BRUNSLI_NOINLINE __declspec(noinline)
151
#elif BRUNSLI_PGI_VERSION_CHECK(10, 2, 0)
152
#define BRUNSLI_NOINLINE _Pragma("noinline")
153
#elif BRUNSLI_TI_VERSION_CHECK(6, 0, 0) && defined(__cplusplus)
154
#define BRUNSLI_NOINLINE _Pragma("FUNC_CANNOT_INLINE;")
155
#elif BRUNSLI_IAR_VERSION_CHECK(8, 0, 0)
156
#define BRUNSLI_NOINLINE _Pragma("inline=never")
157
#else
158
#define BRUNSLI_NOINLINE
159
#endif
160
161
/* BRUNSLI_INTERNAL could be defined to override visibility, e.g. for tests. */
162
#if !defined(BRUNSLI_INTERNAL)
163
#if defined(_WIN32) || defined(__CYGWIN__)
164
#define BRUNSLI_INTERNAL
165
#elif BRUNSLI_GNUC_VERSION_CHECK(3, 3, 0) ||                        \
166
    BRUNSLI_TI_VERSION_CHECK(8, 0, 0) ||                            \
167
    BRUNSLI_INTEL_VERSION_CHECK(16, 0, 0) ||                        \
168
    BRUNSLI_ARM_VERSION_CHECK(4, 1, 0) ||                           \
169
    BRUNSLI_IBM_VERSION_CHECK(13, 1, 0) ||                          \
170
    BRUNSLI_SUNPRO_VERSION_CHECK(5, 11, 0) ||                       \
171
    (BRUNSLI_TI_VERSION_CHECK(7, 3, 0) &&                           \
172
     defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__))
173
#define BRUNSLI_INTERNAL __attribute__ ((visibility ("hidden")))
174
#else
175
#define BRUNSLI_INTERNAL
176
#endif
177
#endif
178
179
/* <<< <<< <<< end of hedley macros. */
180
181
#if BRUNSLI_GNUC_HAS_ATTRIBUTE(unused, 2, 7, 0) || \
182
    BRUNSLI_INTEL_VERSION_CHECK(16, 0, 0)
183
#define BRUNSLI_UNUSED_FUNCTION static BRUNSLI_INLINE __attribute__ ((unused))
184
#else
185
#define BRUNSLI_UNUSED_FUNCTION static BRUNSLI_INLINE
186
#endif
187
188
#if BRUNSLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
189
#define BRUNSLI_ALIGNED(N) __attribute__((aligned(N)))
190
#else
191
#define BRUNSLI_ALIGNED(N)
192
#endif
193
194
#if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \
195
    (defined(M_ARM) && (M_ARM == 7))
196
#define BRUNSLI_TARGET_ARMV7
197
#endif  /* ARMv7 */
198
199
#if (defined(__ARM_ARCH) && (__ARM_ARCH == 8)) || \
200
    defined(__aarch64__) || defined(__ARM64_ARCH_8__)
201
#define BRUNSLI_TARGET_ARMV8_ANY
202
203
#if defined(__ARM_32BIT_STATE)
204
#define BRUNSLI_TARGET_ARMV8_32
205
#elif defined(__ARM_64BIT_STATE)
206
#define BRUNSLI_TARGET_ARMV8_64
207
#endif
208
209
#endif  /* ARMv8 */
210
211
#if defined(__ARM_NEON__) || defined(__ARM_NEON)
212
#define BRUNSLI_TARGET_NEON
213
#endif
214
215
#if defined(__i386) || defined(_M_IX86)
216
#define BRUNSLI_TARGET_X86
217
#endif
218
219
#if defined(__x86_64__) || defined(_M_X64)
220
#define BRUNSLI_TARGET_X64
221
#endif
222
223
#if defined(__PPC64__)
224
#define BRUNSLI_TARGET_POWERPC64
225
#endif
226
227
#if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64
228
#define BRUNSLI_TARGET_RISCV64
229
#endif
230
231
#if defined(BRUNSLI_BUILD_64_BIT)
232
#define BRUNSLI_64_BITS 1
233
#elif defined(BRUNSLI_BUILD_32_BIT)
234
#define BRUNSLI_64_BITS 0
235
#elif defined(BRUNSLI_TARGET_X64) || defined(BRUNSLI_TARGET_ARMV8_64) || \
236
    defined(BRUNSLI_TARGET_POWERPC64) || defined(BRUNSLI_TARGET_RISCV64)
237
#define BRUNSLI_64_BITS 1
238
#else
239
#define BRUNSLI_64_BITS 0
240
#endif
241
242
#if (BRUNSLI_64_BITS)
243
#define brunsli_reg_t uint64_t
244
#else
245
#define brunsli_reg_t uint32_t
246
#endif
247
248
#if defined(BRUNSLI_BUILD_BIG_ENDIAN)
249
#define BRUNSLI_BIG_ENDIAN 1
250
#elif defined(BRUNSLI_BUILD_LITTLE_ENDIAN)
251
#define BRUNSLI_LITTLE_ENDIAN 1
252
#elif defined(BRUNSLI_BUILD_ENDIAN_NEUTRAL)
253
/* Just break elif chain. */
254
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
255
#define BRUNSLI_LITTLE_ENDIAN 1
256
#elif defined(_WIN32) || defined(BRUNSLI_TARGET_X64)
257
/* Win32 & x64 can currently always be assumed to be little endian */
258
#define BRUNSLI_LITTLE_ENDIAN 1
259
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
260
#define BRUNSLI_BIG_ENDIAN 1
261
#elif defined(BRUNSLI_X_BYTE_ORDER)
262
#if BRUNSLI_X_BYTE_ORDER == BRUNSLI_X_LITTLE_ENDIAN
263
#define BRUNSLI_LITTLE_ENDIAN 1
264
#elif BRUNSLI_X_BYTE_ORDER == BRUNSLI_X_BIG_ENDIAN
265
#define BRUNSLI_BIG_ENDIAN 1
266
#endif
267
#endif  /* BRUNSLI_X_BYTE_ORDER */
268
269
#if !defined(BRUNSLI_LITTLE_ENDIAN)
270
#define BRUNSLI_LITTLE_ENDIAN 0
271
#endif
272
273
#if !defined(BRUNSLI_BIG_ENDIAN)
274
#define BRUNSLI_BIG_ENDIAN 0
275
#endif
276
277
#if defined(BRUNSLI_X_BYTE_ORDER)
278
#undef BRUNSLI_X_BYTE_ORDER
279
#undef BRUNSLI_X_LITTLE_ENDIAN
280
#undef BRUNSLI_X_BIG_ENDIAN
281
#endif
282
283
/* Portable unaligned memory access: read / write values via memcpy. */
284
5.54M
static BRUNSLI_INLINE uint16_t BrunsliUnalignedRead16(const void* p) {
285
5.54M
  uint16_t t;
286
5.54M
  memcpy(&t, p, sizeof t);
287
5.54M
  return t;
288
5.54M
}
Unexecuted instantiation: fuzz_decode.cc:BrunsliUnalignedRead16(void const*)
brunsli_decode.cc:BrunsliUnalignedRead16(void const*)
Line
Count
Source
284
5.54M
static BRUNSLI_INLINE uint16_t BrunsliUnalignedRead16(const void* p) {
285
5.54M
  uint16_t t;
286
5.54M
  memcpy(&t, p, sizeof t);
287
5.54M
  return t;
288
5.54M
}
Unexecuted instantiation: context_map_decode.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: histogram_decode.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: huffman_decode.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: jpeg_data_writer.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: state.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: ans_decode.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: bit_reader.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: context.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: lehmer_code.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: platform.cc:BrunsliUnalignedRead16(void const*)
Unexecuted instantiation: quant_matrix.cc:BrunsliUnalignedRead16(void const*)
289
/* Portable unaligned memory access: read / write values via memcpy. */
290
0
static BRUNSLI_INLINE void BrunsliUnalignedWrite16(void* p, uint16_t v) {
291
0
  memcpy(p, &v, sizeof v);
292
0
}
Unexecuted instantiation: fuzz_decode.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: brunsli_decode.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: context_map_decode.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: histogram_decode.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: huffman_decode.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: jpeg_data_writer.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: state.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: ans_decode.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: bit_reader.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: context.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: lehmer_code.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: platform.cc:BrunsliUnalignedWrite16(void*, unsigned short)
Unexecuted instantiation: quant_matrix.cc:BrunsliUnalignedWrite16(void*, unsigned short)
293
0
static BRUNSLI_INLINE uint32_t BrunsliUnalignedRead32(const void* p) {
294
0
  uint32_t t;
295
0
  memcpy(&t, p, sizeof t);
296
0
  return t;
297
0
}
Unexecuted instantiation: fuzz_decode.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: brunsli_decode.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: context_map_decode.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: histogram_decode.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: huffman_decode.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: jpeg_data_writer.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: state.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: ans_decode.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: bit_reader.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: context.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: lehmer_code.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: platform.cc:BrunsliUnalignedRead32(void const*)
Unexecuted instantiation: quant_matrix.cc:BrunsliUnalignedRead32(void const*)
298
0
static BRUNSLI_INLINE uint64_t BrunsliUnalignedRead64(const void* p) {
299
0
  uint64_t t;
300
0
  memcpy(&t, p, sizeof t);
301
0
  return t;
302
0
}
Unexecuted instantiation: fuzz_decode.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: brunsli_decode.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: context_map_decode.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: histogram_decode.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: huffman_decode.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: jpeg_data_writer.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: state.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: ans_decode.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: bit_reader.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: context.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: lehmer_code.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: platform.cc:BrunsliUnalignedRead64(void const*)
Unexecuted instantiation: quant_matrix.cc:BrunsliUnalignedRead64(void const*)
303
0
static BRUNSLI_INLINE void BrunsliUnalignedWrite64(void* p, uint64_t v) {
304
0
  memcpy(p, &v, sizeof v);
305
0
}
Unexecuted instantiation: fuzz_decode.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: brunsli_decode.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: context_map_decode.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: histogram_decode.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: huffman_decode.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: jpeg_data_writer.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: state.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: ans_decode.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: bit_reader.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: context.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: lehmer_code.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: platform.cc:BrunsliUnalignedWrite64(void*, unsigned long)
Unexecuted instantiation: quant_matrix.cc:BrunsliUnalignedWrite64(void*, unsigned long)
306
307
#if BRUNSLI_LITTLE_ENDIAN
308
/* Straight endianness. Just read / write values. */
309
5.54M
#define BRUNSLI_UNALIGNED_LOAD16LE BrunsliUnalignedRead16
310
#define BRUNSLI_UNALIGNED_STORE16LE BrunsliUnalignedWrite16
311
#define BRUNSLI_UNALIGNED_LOAD32LE BrunsliUnalignedRead32
312
#define BRUNSLI_UNALIGNED_LOAD64LE BrunsliUnalignedRead64
313
#define BRUNSLI_UNALIGNED_STORE64LE BrunsliUnalignedWrite64
314
#elif BRUNSLI_BIG_ENDIAN  /* BRUNSLI_LITTLE_ENDIAN */
315
/* Explain compiler to byte-swap values. */
316
#define BRUNSLI_BSWAP16_(V) ((uint16_t)( \
317
  (((V) & 0xFFU) << 8) | \
318
  (((V) >> 8) & 0xFFU)))
319
static BRUNSLI_INLINE uint16_t BRUNSLI_UNALIGNED_LOAD16LE(const void* p) {
320
  uint16_t value = BrunsliUnalignedRead16(p);
321
  return BRUNSLI_BSWAP16_(value);
322
}
323
static BRUNSLI_INLINE void BRUNSLI_UNALIGNED_STORE16LE(void* p, uint16_t v) {
324
  uint16_t value = BRUNSLI_BSWAP16_(v);
325
  BrunsliUnalignedWrite16(p, value);
326
}
327
#define BRUNSLI_BSWAP32_(V) ( \
328
  (((V) & 0xFFU) << 24) | (((V) & 0xFF00U) << 8) | \
329
  (((V) >> 8) & 0xFF00U) | (((V) >> 24) & 0xFFU))
330
static BRUNSLI_INLINE uint32_t BRUNSLI_UNALIGNED_LOAD32LE(const void* p) {
331
  uint32_t value = BrunsliUnalignedRead32(p);
332
  return BRUNSLI_BSWAP32_(value);
333
}
334
#define BRUNSLI_BSWAP64_(V) ( \
335
  (((V) & 0xFFU) << 56) | (((V) & 0xFF00U) << 40) | \
336
  (((V) & 0xFF0000U) << 24) | (((V) & 0xFF000000U) << 8) | \
337
  (((V) >> 8) & 0xFF000000U) | (((V) >> 24) & 0xFF0000U) | \
338
  (((V) >> 40) & 0xFF00U) | (((V) >> 56) & 0xFFU))
339
static BRUNSLI_INLINE uint64_t BRUNSLI_UNALIGNED_LOAD64LE(const void* p) {
340
  uint64_t value = BrunsliUnalignedRead64(p);
341
  return BRUNSLI_BSWAP64_(value);
342
}
343
static BRUNSLI_INLINE void BRUNSLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
344
  uint64_t value = BRUNSLI_BSWAP64_(v);
345
  BrunsliUnalignedWrite64(p, value);
346
}
347
#else  /* BRUNSLI_LITTLE_ENDIAN */
348
/* Read / store values byte-wise; hopefully compiler will understand. */
349
static BRUNSLI_INLINE uint16_t BRUNSLI_UNALIGNED_LOAD16LE(const void* p) {
350
  const uint8_t* in = (const uint8_t*)p;
351
  return (uint16_t)(in[0] | (in[1] << 8));
352
}
353
static BRUNSLI_INLINE void BRUNSLI_UNALIGNED_STORE16LE(void* p, uint16_t v) {
354
  uint8_t* out = (uint8_t*)p;
355
  out[0] = (uint8_t)v;
356
  out[1] = (uint8_t)(v >> 8);
357
}
358
static BRUNSLI_INLINE uint32_t BRUNSLI_UNALIGNED_LOAD32LE(const void* p) {
359
  const uint8_t* in = (const uint8_t*)p;
360
  uint32_t value = (uint32_t)(in[0]);
361
  value |= (uint32_t)(in[1]) << 8;
362
  value |= (uint32_t)(in[2]) << 16;
363
  value |= (uint32_t)(in[3]) << 24;
364
  return value;
365
}
366
static BRUNSLI_INLINE uint64_t BRUNSLI_UNALIGNED_LOAD64LE(const void* p) {
367
  const uint8_t* in = (const uint8_t*)p;
368
  uint64_t value = (uint64_t)(in[0]);
369
  value |= (uint64_t)(in[1]) << 8;
370
  value |= (uint64_t)(in[2]) << 16;
371
  value |= (uint64_t)(in[3]) << 24;
372
  value |= (uint64_t)(in[4]) << 32;
373
  value |= (uint64_t)(in[5]) << 40;
374
  value |= (uint64_t)(in[6]) << 48;
375
  value |= (uint64_t)(in[7]) << 56;
376
  return value;
377
}
378
static BRUNSLI_INLINE void BRUNSLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
379
  uint8_t* out = (uint8_t*)p;
380
  out[0] = (uint8_t)v;
381
  out[1] = (uint8_t)(v >> 8);
382
  out[2] = (uint8_t)(v >> 16);
383
  out[3] = (uint8_t)(v >> 24);
384
  out[4] = (uint8_t)(v >> 32);
385
  out[5] = (uint8_t)(v >> 40);
386
  out[6] = (uint8_t)(v >> 48);
387
  out[7] = (uint8_t)(v >> 56);
388
}
389
#endif  /* BRUNSLI_LITTLE_ENDIAN */
390
391
/* BRUNSLI_IS_CONSTANT macros returns true for compile-time constants. */
392
#if BRUNSLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \
393
    BRUNSLI_INTEL_VERSION_CHECK(16, 0, 0)
394
#define BRUNSLI_IS_CONSTANT(x) (!!__builtin_constant_p(x))
395
#else
396
#define BRUNSLI_IS_CONSTANT(x) (!!0)
397
#endif
398
399
#if defined(BRUNSLI_TARGET_ARMV7) || defined(BRUNSLI_TARGET_ARMV8_ANY)
400
#define BRUNSLI_HAS_UBFX (!!1)
401
#else
402
#define BRUNSLI_HAS_UBFX (!!0)
403
#endif
404
405
// "else" branch is never evaluated, but provides the sink.
406
4.06k
#define BRUNSLI_VOID_LOG() if (true) {} else std::cerr
407
408
// This macro allows easy logging engine replacement.
409
#if defined(BRUNSLI_USE_LOGGING)
410
#define BRUNSLI_LOG_(LEVEL) LOG(LEVEL)
411
#define BRUNSLI_ENDL() ""
412
#else  // defined(BRUNSLI_USE_LOGGING)
413
1.20k
#define BRUNSLI_LOG_(LEVEL) std::cerr
414
334
#define BRUNSLI_ENDL() std::endl
415
#endif  // defined(BRUNSLI_USE_LOGGING)
416
417
#if defined(BRUNSLI_DISABLE_LOG)
418
#define BRUNSLI_LOG_DEBUG() BRUNSLI_VOID_LOG()
419
#define BRUNSLI_LOG_INFO() BRUNSLI_VOID_LOG()
420
#define BRUNSLI_LOG_WARNING() BRUNSLI_VOID_LOG()
421
#define BRUNSLI_LOG_ERROR() BRUNSLI_VOID_LOG()
422
#else  // defined(BRUNSLI_DISABLE_LOG)
423
// TODO(eustas): get rid of base/logging.h dependency
424
#if defined(BRUNSLI_ENABLE_LOG)
425
#define BRUNSLI_LOG_DEBUG() BRUNSLI_LOG_(INFO)
426
#else  //  defined(BRUNSLI_ENABLE_LOG)
427
4.06k
#define BRUNSLI_LOG_DEBUG() BRUNSLI_VOID_LOG()
428
#endif  //  defined(BRUNSLI_ENABLE_LOG)
429
#define BRUNSLI_LOG_INFO() BRUNSLI_LOG_(INFO)
430
#define BRUNSLI_LOG_WARNING() BRUNSLI_LOG_(WARNING)
431
334
#define BRUNSLI_LOG_ERROR() BRUNSLI_LOG_(ERROR)
432
#endif  // defined(BRUNSLI_DISABLE_LOG)
433
434
namespace brunsli {
435
void BrunsliDumpAndAbort(const char* f, int l, const char* fn);
436
static BRUNSLI_INLINE void Append(std::vector<uint8_t>* dst,
437
251k
                                  const uint8_t* begin, const uint8_t* end) {
438
251k
  dst->insert(dst->end(), begin, end);
439
251k
}
Unexecuted instantiation: fuzz_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
brunsli_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Line
Count
Source
437
251k
                                  const uint8_t* begin, const uint8_t* end) {
438
251k
  dst->insert(dst->end(), begin, end);
439
251k
}
Unexecuted instantiation: context_map_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: histogram_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: huffman_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: state.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: ans_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: bit_reader.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: context.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: lehmer_code.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: platform.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
Unexecuted instantiation: quant_matrix.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned char const*)
440
static BRUNSLI_INLINE void Append(std::vector<uint8_t>* dst,
441
201k
                                  const uint8_t* begin, size_t length) {
442
201k
  Append(dst, begin, begin + length);
443
201k
}
Unexecuted instantiation: fuzz_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
brunsli_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Line
Count
Source
441
201k
                                  const uint8_t* begin, size_t length) {
442
201k
  Append(dst, begin, begin + length);
443
201k
}
Unexecuted instantiation: context_map_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: histogram_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: huffman_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: state.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: ans_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: bit_reader.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: context.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: lehmer_code.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: platform.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
Unexecuted instantiation: quant_matrix.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, unsigned char const*, unsigned long)
444
static BRUNSLI_INLINE void Append(std::vector<uint8_t>* dst,
445
0
                                  const std::vector<uint8_t>& src) {
446
0
  Append(dst, src.data(), src.size());
447
0
}
Unexecuted instantiation: fuzz_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: brunsli_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: context_map_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: histogram_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: huffman_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: state.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: ans_decode.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: bit_reader.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: context.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: lehmer_code.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: platform.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: quant_matrix.cc:brunsli::Append(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
448
}  // namespace brunsli
449
450
// TODO(eustas): use "predict false" to move the code out of hot path.
451
#define BRUNSLI_CHECK(V) \
452
0
  if (!(V)) {                                                         \
453
0
    ::brunsli::BrunsliDumpAndAbort(__FILE__, __LINE__, __FUNCTION__); \
454
0
    /* Tell the compiler, that there is no escape route. */           \
455
0
    while (true) ;                                                    \
456
0
  }
457
458
#if defined(BRUNSLI_DEBUG)
459
#define BRUNSLI_DCHECK(V) BRUNSLI_CHECK(V)
460
#else
461
#define BRUNSLI_DCHECK(V)
462
#endif
463
464
// TODO(eustas): Pick up upgrade after https://github.com/google/brotli/pull/636
465
//               is landed and merged.
466
20.2M
inline int Log2FloorNonZero(uint32_t n) {
467
20.2M
#ifdef __GNUC__
468
20.2M
  return 31 ^ __builtin_clz(n);
469
#else
470
  unsigned int result = 0;
471
  while (n >>= 1) result++;
472
  return result;
473
#endif
474
20.2M
}
475
476
680
#define BRUNSLI_UNUSED(X) (void)(X)
477
478
0
BRUNSLI_UNUSED_FUNCTION void BrunsliSuppressUnusedFunctions(void) {
479
0
  BRUNSLI_UNUSED(
480
0
      static_cast<void (*)(std::vector<uint8_t>*, const std::vector<uint8_t>&)>(
481
0
          &brunsli::Append));
482
0
  BRUNSLI_UNUSED(&BrunsliSuppressUnusedFunctions);
483
0
  BRUNSLI_UNUSED(&BrunsliUnalignedRead16);
484
0
  BRUNSLI_UNUSED(&BrunsliUnalignedWrite16);
485
0
  BRUNSLI_UNUSED(&BrunsliUnalignedRead32);
486
0
  BRUNSLI_UNUSED(&BrunsliUnalignedRead64);
487
0
  BRUNSLI_UNUSED(&BrunsliUnalignedWrite64);
488
0
  BRUNSLI_UNUSED(&BRUNSLI_UNALIGNED_LOAD16LE);
489
0
  BRUNSLI_UNUSED(&BRUNSLI_UNALIGNED_STORE16LE);
490
0
  BRUNSLI_UNUSED(&BRUNSLI_UNALIGNED_LOAD32LE);
491
0
  BRUNSLI_UNUSED(&BRUNSLI_UNALIGNED_LOAD64LE);
492
0
  BRUNSLI_UNUSED(&BRUNSLI_UNALIGNED_STORE64LE);
493
0
}
Unexecuted instantiation: fuzz_decode.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: brunsli_decode.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: context_map_decode.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: histogram_decode.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: huffman_decode.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: jpeg_data_writer.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: state.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: ans_decode.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: bit_reader.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: context.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: lehmer_code.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: platform.cc:BrunsliSuppressUnusedFunctions()
Unexecuted instantiation: quant_matrix.cc:BrunsliSuppressUnusedFunctions()
494
495
#endif  // BRUNSLI_COMMON_PLATFORM_H_