Coverage Report

Created: 2025-11-16 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/jxl/fields.cc
Line
Count
Source
1
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
2
//
3
// Use of this source code is governed by a BSD-style
4
// license that can be found in the LICENSE file.
5
6
#include "lib/jxl/fields.h"
7
8
#include <algorithm>
9
#include <cinttypes>  // PRIu64
10
#include <cmath>
11
#include <cstddef>
12
#include <cstring>
13
#include <hwy/base.h>
14
15
#include "lib/jxl/base/bits.h"
16
#include "lib/jxl/base/common.h"
17
#include "lib/jxl/base/compiler_specific.h"
18
#include "lib/jxl/base/printf_macros.h"
19
#include "lib/jxl/base/status.h"
20
#include "lib/jxl/dec_bit_reader.h"
21
#include "lib/jxl/field_encodings.h"
22
23
namespace jxl {
24
25
namespace {
26
27
using ::jxl::fields_internal::VisitorBase;
28
29
struct InitVisitor : public VisitorBase {
30
  Status Bits(const size_t /*unused*/, const uint32_t default_value,
31
26.4M
              uint32_t* JXL_RESTRICT value) override {
32
26.4M
    *value = default_value;
33
26.4M
    return true;
34
26.4M
  }
35
36
  Status U32(const U32Enc /*unused*/, const uint32_t default_value,
37
108M
             uint32_t* JXL_RESTRICT value) override {
38
108M
    *value = default_value;
39
108M
    return true;
40
108M
  }
41
42
  Status U64(const uint64_t default_value,
43
3.45M
             uint64_t* JXL_RESTRICT value) override {
44
3.45M
    *value = default_value;
45
3.45M
    return true;
46
3.45M
  }
47
48
60.7M
  Status Bool(bool default_value, bool* JXL_RESTRICT value) override {
49
60.7M
    *value = default_value;
50
60.7M
    return true;
51
60.7M
  }
52
53
284M
  Status F16(const float default_value, float* JXL_RESTRICT value) override {
54
284M
    *value = default_value;
55
284M
    return true;
56
284M
  }
57
58
  // Always visit conditional fields to ensure they are initialized.
59
94.2M
  Status Conditional(bool /*condition*/) override { return true; }
60
61
  Status AllDefault(const Fields& /*fields*/,
62
16.4M
                    bool* JXL_RESTRICT all_default) override {
63
    // Just initialize this field and don't skip initializing others.
64
16.4M
    JXL_RETURN_IF_ERROR(Bool(true, all_default));
65
16.4M
    return false;
66
16.4M
  }
67
68
33.9M
  Status VisitNested(Fields* /*fields*/) override {
69
    // Avoid re-initializing nested bundles (their ctors already called
70
    // Bundle::Init for their fields).
71
33.9M
    return true;
72
33.9M
  }
73
};
74
75
// Similar to InitVisitor, but also initializes nested fields.
76
struct SetDefaultVisitor : public VisitorBase {
77
  Status Bits(const size_t /*unused*/, const uint32_t default_value,
78
1.87M
              uint32_t* JXL_RESTRICT value) override {
79
1.87M
    *value = default_value;
80
1.87M
    return true;
81
1.87M
  }
82
83
  Status U32(const U32Enc /*unused*/, const uint32_t default_value,
84
9.88M
             uint32_t* JXL_RESTRICT value) override {
85
9.88M
    *value = default_value;
86
9.88M
    return true;
87
9.88M
  }
88
89
  Status U64(const uint64_t default_value,
90
170k
             uint64_t* JXL_RESTRICT value) override {
91
170k
    *value = default_value;
92
170k
    return true;
93
170k
  }
94
95
5.35M
  Status Bool(bool default_value, bool* JXL_RESTRICT value) override {
96
5.35M
    *value = default_value;
97
5.35M
    return true;
98
5.35M
  }
99
100
91.6M
  Status F16(const float default_value, float* JXL_RESTRICT value) override {
101
91.6M
    *value = default_value;
102
91.6M
    return true;
103
91.6M
  }
104
105
  // Always visit conditional fields to ensure they are initialized.
106
8.44M
  Status Conditional(bool /*condition*/) override { return true; }
107
108
  Status AllDefault(const Fields& /*fields*/,
109
1.93M
                    bool* JXL_RESTRICT all_default) override {
110
    // Just initialize this field and don't skip initializing others.
111
1.93M
    JXL_RETURN_IF_ERROR(Bool(true, all_default));
112
1.93M
    return false;
113
1.93M
  }
114
};
115
116
class AllDefaultVisitor : public VisitorBase {
117
 public:
118
1.29M
  explicit AllDefaultVisitor() = default;
119
120
  Status Bits(const size_t bits, const uint32_t default_value,
121
1.44M
              uint32_t* JXL_RESTRICT value) override {
122
1.44M
    all_default_ &= *value == default_value;
123
1.44M
    return true;
124
1.44M
  }
125
126
  Status U32(const U32Enc /*unused*/, const uint32_t default_value,
127
53.9k
             uint32_t* JXL_RESTRICT value) override {
128
53.9k
    all_default_ &= *value == default_value;
129
53.9k
    return true;
130
53.9k
  }
131
132
  Status U64(const uint64_t default_value,
133
21.7k
             uint64_t* JXL_RESTRICT value) override {
134
21.7k
    all_default_ &= *value == default_value;
135
21.7k
    return true;
136
21.7k
  }
137
138
3.85M
  Status F16(const float default_value, float* JXL_RESTRICT value) override {
139
3.85M
    all_default_ &= std::abs(*value - default_value) < 1E-6f;
140
3.85M
    return true;
141
3.85M
  }
142
143
  Status AllDefault(const Fields& /*fields*/,
144
1.30M
                    bool* JXL_RESTRICT /*all_default*/) override {
145
    // Visit all fields so we can compute the actual all_default_ value.
146
1.30M
    return false;
147
1.30M
  }
148
149
1.29M
  bool AllDefault() const { return all_default_; }
150
151
 private:
152
  bool all_default_ = true;
153
};
154
155
class ReadVisitor : public VisitorBase {
156
 public:
157
2.65M
  explicit ReadVisitor(BitReader* reader) : reader_(reader) {}
158
159
  Status Bits(const size_t bits, const uint32_t /*default_value*/,
160
12.5M
              uint32_t* JXL_RESTRICT value) override {
161
12.5M
    *value = BitsCoder::Read(bits, reader_);
162
12.5M
    if (!reader_->AllReadsWithinBounds()) {
163
40.6k
      return JXL_NOT_ENOUGH_BYTES("Not enough bytes for header");
164
40.6k
    }
165
12.5M
    return true;
166
12.5M
  }
167
168
  Status U32(const U32Enc dist, const uint32_t /*default_value*/,
169
5.51M
             uint32_t* JXL_RESTRICT value) override {
170
5.51M
    *value = U32Coder::Read(dist, reader_);
171
5.51M
    if (!reader_->AllReadsWithinBounds()) {
172
30.4k
      return JXL_NOT_ENOUGH_BYTES("Not enough bytes for header");
173
30.4k
    }
174
5.48M
    return true;
175
5.51M
  }
176
177
  Status U64(const uint64_t /*default_value*/,
178
2.19M
             uint64_t* JXL_RESTRICT value) override {
179
2.19M
    *value = U64Coder::Read(reader_);
180
2.19M
    if (!reader_->AllReadsWithinBounds()) {
181
9.60k
      return JXL_NOT_ENOUGH_BYTES("Not enough bytes for header");
182
9.60k
    }
183
2.18M
    return true;
184
2.19M
  }
185
186
  Status F16(const float /*default_value*/,
187
324k
             float* JXL_RESTRICT value) override {
188
324k
    ok_ &= F16Coder::Read(reader_, value);
189
324k
    if (!reader_->AllReadsWithinBounds()) {
190
12.3k
      return JXL_NOT_ENOUGH_BYTES("Not enough bytes for header");
191
12.3k
    }
192
311k
    return true;
193
324k
  }
194
195
1.42M
  void SetDefault(Fields* fields) override { Bundle::SetDefault(fields); }
196
197
2.10M
  bool IsReading() const override { return true; }
198
199
  // This never fails because visitors are expected to keep reading until
200
  // EndExtensions, see comment there.
201
811k
  Status BeginExtensions(uint64_t* JXL_RESTRICT extensions) override {
202
811k
    JXL_QUIET_RETURN_IF_ERROR(VisitorBase::BeginExtensions(extensions));
203
810k
    if (*extensions == 0) return true;
204
205
    // For each nonzero bit, i.e. extension that is present:
206
1.69M
    for (uint64_t remaining_extensions = *extensions; remaining_extensions != 0;
207
1.21M
         remaining_extensions &= remaining_extensions - 1) {
208
1.21M
      const size_t idx_extension =
209
1.21M
          Num0BitsBelowLS1Bit_Nonzero(remaining_extensions);
210
      // Read additional U64 (one per extension) indicating the number of bits
211
      // (allows skipping individual extensions).
212
1.21M
      JXL_RETURN_IF_ERROR(U64(0, &extension_bits_[idx_extension]));
213
1.20M
      if (!SafeAdd(total_extension_bits_, extension_bits_[idx_extension],
214
1.20M
                   total_extension_bits_)) {
215
525
        return JXL_FAILURE("Extension bits overflowed, invalid codestream");
216
525
      }
217
1.20M
    }
218
    // Used by EndExtensions to skip past any _remaining_ extensions.
219
477k
    pos_after_ext_size_ = reader_->TotalBitsConsumed();
220
477k
    JXL_ENSURE(pos_after_ext_size_ != 0);
221
477k
    return true;
222
477k
  }
223
224
801k
  Status EndExtensions() override {
225
801k
    JXL_QUIET_RETURN_IF_ERROR(VisitorBase::EndExtensions());
226
    // Happens if extensions == 0: don't read size, done.
227
801k
    if (pos_after_ext_size_ == 0) return true;
228
229
    // Not enough bytes as set by BeginExtensions or earlier. Do not return
230
    // this as a JXL_FAILURE or false (which can also propagate to error
231
    // through e.g. JXL_RETURN_IF_ERROR), since this may be used while
232
    // silently checking whether there are enough bytes. If this case must be
233
    // treated as an error, reader_>Close() will do this, just like is already
234
    // done for non-extension fields.
235
478k
    if (!enough_bytes_) return true;
236
237
    // Skip new fields this (old?) decoder didn't know about, if any.
238
478k
    const size_t bits_read = reader_->TotalBitsConsumed();
239
478k
    uint64_t end;
240
478k
    if (!SafeAdd(pos_after_ext_size_, total_extension_bits_, end)) {
241
78
      return JXL_FAILURE("Invalid extension size, caused overflow");
242
78
    }
243
478k
    if (bits_read > end) {
244
1.21k
      return JXL_FAILURE("Read more extension bits than budgeted");
245
1.21k
    }
246
477k
    const size_t remaining_bits = end - bits_read;
247
477k
    if (remaining_bits != 0) {
248
92.6k
      JXL_WARNING("Skipping %" PRIuS "-bit extension(s)", remaining_bits);
249
92.6k
      reader_->SkipBits(remaining_bits);
250
92.6k
      if (!reader_->AllReadsWithinBounds()) {
251
21.2k
        return JXL_NOT_ENOUGH_BYTES("Not enough bytes for header");
252
21.2k
      }
253
92.6k
    }
254
456k
    return true;
255
477k
  }
256
257
1.52M
  Status OK() const { return ok_; }
258
259
 private:
260
  // Whether any error other than not enough bytes occurred.
261
  bool ok_ = true;
262
263
  // Whether there are enough input bytes to read from.
264
  bool enough_bytes_ = true;
265
  BitReader* const reader_;
266
  // May be 0 even if the corresponding extension is present.
267
  uint64_t extension_bits_[Bundle::kMaxExtensions] = {0};
268
  uint64_t total_extension_bits_ = 0;
269
  size_t pos_after_ext_size_ = 0;  // 0 iff extensions == 0.
270
271
  friend Status jxl::CheckHasEnoughBits(Visitor* /* visitor */,
272
                                        size_t /* bits */);
273
};
274
275
class CanEncodeVisitor : public VisitorBase {
276
 public:
277
83.8k
  explicit CanEncodeVisitor() = default;
278
279
  Status Bits(const size_t bits, const uint32_t /*default_value*/,
280
119k
              uint32_t* JXL_RESTRICT value) override {
281
119k
    size_t encoded_bits = 0;
282
119k
    ok_ &= BitsCoder::CanEncode(bits, *value, &encoded_bits);
283
119k
    encoded_bits_ += encoded_bits;
284
119k
    return true;
285
119k
  }
286
287
  Status U32(const U32Enc enc, const uint32_t /*default_value*/,
288
50.1k
             uint32_t* JXL_RESTRICT value) override {
289
50.1k
    size_t encoded_bits = 0;
290
50.1k
    ok_ &= U32Coder::CanEncode(enc, *value, &encoded_bits);
291
50.1k
    encoded_bits_ += encoded_bits;
292
50.1k
    return true;
293
50.1k
  }
294
295
  Status U64(const uint64_t /*default_value*/,
296
9.06k
             uint64_t* JXL_RESTRICT value) override {
297
9.06k
    size_t encoded_bits = 0;
298
9.06k
    ok_ &= U64Coder::CanEncode(*value, &encoded_bits);
299
9.06k
    encoded_bits_ += encoded_bits;
300
9.06k
    return true;
301
9.06k
  }
302
303
  Status F16(const float /*default_value*/,
304
0
             float* JXL_RESTRICT value) override {
305
0
    size_t encoded_bits = 0;
306
0
    ok_ &= F16Coder::CanEncode(*value, &encoded_bits);
307
0
    encoded_bits_ += encoded_bits;
308
0
    return true;
309
0
  }
310
311
  Status AllDefault(const Fields& fields,
312
24.4k
                    bool* JXL_RESTRICT all_default) override {
313
24.4k
    *all_default = Bundle::AllDefault(fields);
314
24.4k
    JXL_RETURN_IF_ERROR(Bool(true, all_default));
315
24.4k
    return *all_default;
316
24.4k
  }
317
318
5.60k
  Status BeginExtensions(uint64_t* JXL_RESTRICT extensions) override {
319
5.60k
    JXL_QUIET_RETURN_IF_ERROR(VisitorBase::BeginExtensions(extensions));
320
5.60k
    extensions_ = *extensions;
321
5.60k
    if (*extensions != 0) {
322
0
      JXL_ENSURE(pos_after_ext_ == 0);
323
0
      pos_after_ext_ = encoded_bits_;
324
0
      JXL_ENSURE(pos_after_ext_ != 0);  // visited "extensions"
325
0
    }
326
5.60k
    return true;
327
5.60k
  }
328
  // EndExtensions = default.
329
330
  Status GetSizes(size_t* JXL_RESTRICT extension_bits,
331
83.8k
                  size_t* JXL_RESTRICT total_bits) {
332
83.8k
    JXL_RETURN_IF_ERROR(ok_);
333
83.8k
    *extension_bits = 0;
334
83.8k
    *total_bits = encoded_bits_;
335
    // Only if extension field was nonzero will we encode their sizes.
336
83.8k
    if (pos_after_ext_ != 0) {
337
0
      JXL_ENSURE(encoded_bits_ >= pos_after_ext_);
338
0
      *extension_bits = encoded_bits_ - pos_after_ext_;
339
      // Also need to encode *extension_bits and bill it to *total_bits.
340
0
      size_t encoded_bits = 0;
341
0
      ok_ &= U64Coder::CanEncode(*extension_bits, &encoded_bits);
342
0
      *total_bits += encoded_bits;
343
344
      // TODO(janwas): support encoding individual extension sizes. We
345
      // currently ascribe all bits to the first and send zeros for the
346
      // others.
347
0
      for (size_t i = 1; i < hwy::PopCount(extensions_); ++i) {
348
0
        encoded_bits = 0;
349
0
        ok_ &= U64Coder::CanEncode(0, &encoded_bits);
350
0
        *total_bits += encoded_bits;
351
0
      }
352
0
    }
353
83.8k
    return true;
354
83.8k
  }
355
356
 private:
357
  bool ok_ = true;
358
  size_t encoded_bits_ = 0;
359
  uint64_t extensions_ = 0;
360
  // Snapshot of encoded_bits_ after visiting the extension field, but NOT
361
  // including the hidden extension sizes.
362
  uint64_t pos_after_ext_ = 0;
363
};
364
}  // namespace
365
366
50.0M
void Bundle::Init(Fields* fields) {
367
50.0M
  InitVisitor visitor;
368
50.0M
  if (!visitor.Visit(fields)) {
369
0
    JXL_DEBUG_ABORT("Init should never fail");
370
0
  }
371
50.0M
}
372
1.42M
void Bundle::SetDefault(Fields* fields) {
373
1.42M
  SetDefaultVisitor visitor;
374
1.42M
  if (!visitor.Visit(fields)) {
375
0
    JXL_DEBUG_ABORT("SetDefault should never fail");
376
0
  }
377
1.42M
}
378
1.29M
bool Bundle::AllDefault(const Fields& fields) {
379
1.29M
  AllDefaultVisitor visitor;
380
1.29M
  if (!visitor.VisitConst(fields)) {
381
0
    JXL_DEBUG_ABORT("AllDefault should never fail");
382
0
  }
383
1.29M
  return visitor.AllDefault();
384
1.29M
}
385
Status Bundle::CanEncode(const Fields& fields, size_t* extension_bits,
386
83.8k
                         size_t* total_bits) {
387
83.8k
  CanEncodeVisitor visitor;
388
83.8k
  JXL_QUIET_RETURN_IF_ERROR(visitor.VisitConst(fields));
389
83.8k
  JXL_QUIET_RETURN_IF_ERROR(visitor.GetSizes(extension_bits, total_bits));
390
83.8k
  return true;
391
83.8k
}
392
1.63M
Status Bundle::Read(BitReader* reader, Fields* fields) {
393
1.63M
  ReadVisitor visitor(reader);
394
1.63M
  JXL_RETURN_IF_ERROR(visitor.Visit(fields));
395
1.52M
  return visitor.OK();
396
1.63M
}
397
1.01M
bool Bundle::CanRead(BitReader* reader, Fields* fields) {
398
1.01M
  ReadVisitor visitor(reader);
399
1.01M
  Status status = visitor.Visit(fields);
400
  // We are only checking here whether there are enough bytes. We still return
401
  // true for other errors because it means there are enough bytes to determine
402
  // there's an error. Use Read() to determine which error it is.
403
1.01M
  return status.code() != StatusCode::kNotEnoughBytes;
404
1.01M
}
405
406
0
size_t BitsCoder::MaxEncodedBits(const size_t bits) { return bits; }
407
408
Status BitsCoder::CanEncode(const size_t bits, const uint32_t value,
409
119k
                            size_t* JXL_RESTRICT encoded_bits) {
410
119k
  *encoded_bits = bits;
411
119k
  if (value >= (1ULL << bits)) {
412
0
    return JXL_FAILURE("Value %u too large for %" PRIu64 " bits", value,
413
0
                       static_cast<uint64_t>(bits));
414
0
  }
415
119k
  return true;
416
119k
}
417
418
12.5M
uint32_t BitsCoder::Read(const size_t bits, BitReader* JXL_RESTRICT reader) {
419
12.5M
  return reader->ReadBits(bits);
420
12.5M
}
421
422
4.93k
size_t U32Coder::MaxEncodedBits(const U32Enc enc) {
423
4.93k
  size_t extra_bits = 0;
424
24.6k
  for (uint32_t selector = 0; selector < 4; ++selector) {
425
19.7k
    const U32Distr d = enc.GetDistr(selector);
426
19.7k
    if (d.IsDirect()) {
427
0
      continue;
428
19.7k
    } else {
429
19.7k
      extra_bits = std::max<size_t>(extra_bits, d.ExtraBits());
430
19.7k
    }
431
19.7k
  }
432
4.93k
  return 2 + extra_bits;
433
4.93k
}
434
435
Status U32Coder::CanEncode(const U32Enc enc, const uint32_t value,
436
53.6k
                           size_t* JXL_RESTRICT encoded_bits) {
437
53.6k
  uint32_t selector;
438
53.6k
  size_t total_bits;
439
53.6k
  const Status ok = ChooseSelector(enc, value, &selector, &total_bits);
440
53.6k
  *encoded_bits = ok ? total_bits : 0;
441
53.6k
  return ok;
442
53.6k
}
443
444
7.19M
uint32_t U32Coder::Read(const U32Enc enc, BitReader* JXL_RESTRICT reader) {
445
7.19M
  const uint32_t selector = reader->ReadFixedBits<2>();
446
7.19M
  const U32Distr d = enc.GetDistr(selector);
447
7.19M
  if (d.IsDirect()) {
448
3.78M
    return d.Direct();
449
3.78M
  } else {
450
3.41M
    return reader->ReadBits(d.ExtraBits()) + d.Offset();
451
3.41M
  }
452
7.19M
}
453
454
Status U32Coder::ChooseSelector(const U32Enc enc, const uint32_t value,
455
                                uint32_t* JXL_RESTRICT selector,
456
117k
                                size_t* JXL_RESTRICT total_bits) {
457
117k
  const size_t bits_required = 32 - Num0BitsAboveMS1Bit(value);
458
117k
  JXL_ENSURE(bits_required <= 32);
459
460
117k
  *selector = 0;
461
117k
  *total_bits = 0;
462
463
  // It is difficult to verify whether Dist32Byte are sorted, so check all
464
  // selectors and keep the one with the fewest total_bits.
465
117k
  *total_bits = 64;  // more than any valid encoding
466
339k
  for (uint32_t s = 0; s < 4; ++s) {
467
288k
    const U32Distr d = enc.GetDistr(s);
468
288k
    if (d.IsDirect()) {
469
109k
      if (d.Direct() == value) {
470
67.2k
        *selector = s;
471
67.2k
        *total_bits = 2;
472
67.2k
        return true;  // Done, direct is always the best possible.
473
67.2k
      }
474
41.9k
      continue;
475
109k
    }
476
179k
    const size_t extra_bits = d.ExtraBits();
477
179k
    const uint32_t offset = d.Offset();
478
179k
    if (value < offset || value >= offset + (1ULL << extra_bits)) continue;
479
480
    // Better than prior encoding, remember it:
481
92.4k
    if (2 + extra_bits < *total_bits) {
482
50.6k
      *selector = s;
483
50.6k
      *total_bits = 2 + extra_bits;
484
50.6k
    }
485
92.4k
  }
486
487
50.6k
  if (*total_bits == 64) {
488
0
    return JXL_FAILURE("No feasible selector for %u", value);
489
0
  }
490
491
50.6k
  return true;
492
50.6k
}
493
494
2.22M
uint64_t U64Coder::Read(BitReader* JXL_RESTRICT reader) {
495
2.22M
  uint64_t selector = reader->ReadFixedBits<2>();
496
2.22M
  if (selector == 0) {
497
1.37M
    return 0;
498
1.37M
  }
499
849k
  if (selector == 1) {
500
394k
    return 1 + reader->ReadFixedBits<4>();
501
394k
  }
502
455k
  if (selector == 2) {
503
242k
    return 17 + reader->ReadFixedBits<8>();
504
242k
  }
505
506
  // selector 3, varint, groups have first 12, then 8, and last 4 bits.
507
213k
  uint64_t result = reader->ReadFixedBits<12>();
508
509
213k
  uint64_t shift = 12;
510
310k
  while (reader->ReadFixedBits<1>()) {
511
99.8k
    if (shift == 60) {
512
2.61k
      result |= static_cast<uint64_t>(reader->ReadFixedBits<4>()) << shift;
513
2.61k
      break;
514
2.61k
    }
515
97.2k
    result |= static_cast<uint64_t>(reader->ReadFixedBits<8>()) << shift;
516
97.2k
    shift += 8;
517
97.2k
  }
518
519
213k
  return result;
520
455k
}
521
522
// Can always encode, but useful because it also returns bit size.
523
9.06k
Status U64Coder::CanEncode(uint64_t value, size_t* JXL_RESTRICT encoded_bits) {
524
9.06k
  if (value == 0) {
525
7.61k
    *encoded_bits = 2;  // 2 selector bits
526
7.61k
  } else if (value <= 16) {
527
1.44k
    *encoded_bits = 2 + 4;  // 2 selector bits + 4 payload bits
528
1.44k
  } else if (value <= 272) {
529
0
    *encoded_bits = 2 + 8;  // 2 selector bits + 8 payload bits
530
0
  } else {
531
0
    *encoded_bits = 2 + 12;  // 2 selector bits + 12 payload bits
532
0
    value >>= 12;
533
0
    int shift = 12;
534
0
    while (value > 0 && shift < 60) {
535
0
      *encoded_bits += 1 + 8;  // 1 continuation bit + 8 payload bits
536
0
      value >>= 8;
537
0
      shift += 8;
538
0
    }
539
0
    if (value > 0) {
540
      // This only could happen if shift == N - 4.
541
0
      *encoded_bits += 1 + 4;  // 1 continuation bit + 4 payload bits
542
0
    } else {
543
0
      *encoded_bits += 1;  // 1 stop bit
544
0
    }
545
0
  }
546
547
9.06k
  return true;
548
9.06k
}
549
550
Status F16Coder::Read(BitReader* JXL_RESTRICT reader,
551
434k
                      float* JXL_RESTRICT value) {
552
434k
  const uint32_t bits16 = reader->ReadFixedBits<16>();
553
434k
  const uint32_t sign = bits16 >> 15;
554
434k
  const uint32_t biased_exp = (bits16 >> 10) & 0x1F;
555
434k
  const uint32_t mantissa = bits16 & 0x3FF;
556
557
434k
  if (JXL_UNLIKELY(biased_exp == 31)) {
558
7.54k
    return JXL_FAILURE("F16 infinity or NaN are not supported");
559
7.54k
  }
560
561
  // Subnormal or zero
562
426k
  if (JXL_UNLIKELY(biased_exp == 0)) {
563
202k
    *value = (1.0f / 16384) * (mantissa * (1.0f / 1024));
564
202k
    if (sign) *value = -*value;
565
202k
    return true;
566
202k
  }
567
568
  // Normalized: convert the representation directly (faster than ldexp/tables).
569
224k
  const uint32_t biased_exp32 = biased_exp + (127 - 15);
570
224k
  const uint32_t mantissa32 = mantissa << (23 - 10);
571
224k
  const uint32_t bits32 = (sign << 31) | (biased_exp32 << 23) | mantissa32;
572
224k
  memcpy(value, &bits32, sizeof(bits32));
573
224k
  return true;
574
426k
}
575
576
0
Status F16Coder::CanEncode(float value, size_t* JXL_RESTRICT encoded_bits) {
577
0
  *encoded_bits = MaxEncodedBits();
578
0
  if (std::isnan(value) || std::isinf(value)) {
579
0
    return JXL_FAILURE("Should not attempt to store NaN and infinity");
580
0
  }
581
0
  return std::abs(value) <= 65504.0f;
582
0
}
583
584
0
Status CheckHasEnoughBits(Visitor* visitor, size_t bits) {
585
0
  if (!visitor->IsReading()) return false;
586
0
  ReadVisitor* rv = static_cast<ReadVisitor*>(visitor);
587
0
  size_t have_bits = rv->reader_->TotalBytes() * kBitsPerByte;
588
0
  size_t want_bits = bits + rv->reader_->TotalBitsConsumed();
589
0
  if (have_bits < want_bits) {
590
0
    return JXL_NOT_ENOUGH_BYTES("Not enough bytes for header");
591
0
  }
592
0
  return true;
593
0
}
594
595
}  // namespace jxl