Coverage Report

Created: 2024-09-08 07:14

/src/libjxl/lib/jpegli/common_internal.h
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
#ifndef LIB_JPEGLI_COMMON_INTERNAL_H_
7
#define LIB_JPEGLI_COMMON_INTERNAL_H_
8
9
#include <cstddef>
10
#include <cstdint>
11
#include <cstring>
12
13
// Suppress any -Wdeprecated-declarations warning that might be emitted by
14
// GCC or Clang by std::stable_sort in C++17 or later mode
15
#ifdef __clang__
16
#pragma clang diagnostic push
17
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
18
#elif defined(__GNUC__)
19
#pragma GCC push_options
20
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
21
#endif
22
23
#include <algorithm>
24
25
#ifdef __clang__
26
#pragma clang diagnostic pop
27
#elif defined(__GNUC__)
28
#pragma GCC pop_options
29
#endif
30
31
#include <hwy/aligned_allocator.h>
32
33
#include "lib/jpegli/memory_manager.h"
34
#include "lib/jpegli/simd.h"
35
#include "lib/jxl/base/compiler_specific.h"  // for ssize_t
36
37
namespace jpegli {
38
39
enum State {
40
  kDecNull,
41
  kDecStart,
42
  kDecInHeader,
43
  kDecHeaderDone,
44
  kDecProcessMarkers,
45
  kDecProcessScan,
46
  kEncNull,
47
  kEncStart,
48
  kEncHeader,
49
  kEncReadImage,
50
  kEncWriteCoeffs,
51
};
52
53
template <typename T1, typename T2>
54
17.2M
constexpr inline T1 DivCeil(T1 a, T2 b) {
55
17.2M
  return (a + b - 1) / b;
56
17.2M
}
unsigned long jpegli::DivCeil<unsigned long, unsigned long>(unsigned long, unsigned long)
Line
Count
Source
54
17.3k
constexpr inline T1 DivCeil(T1 a, T2 b) {
55
17.3k
  return (a + b - 1) / b;
56
17.3k
}
unsigned int jpegli::DivCeil<unsigned int, int>(unsigned int, int)
Line
Count
Source
54
43.5k
constexpr inline T1 DivCeil(T1 a, T2 b) {
55
43.5k
  return (a + b - 1) / b;
56
43.5k
}
unsigned long jpegli::DivCeil<unsigned long, int>(unsigned long, int)
Line
Count
Source
54
16.0M
constexpr inline T1 DivCeil(T1 a, T2 b) {
55
16.0M
  return (a + b - 1) / b;
56
16.0M
}
int jpegli::DivCeil<int, int>(int, int)
Line
Count
Source
54
1.10M
constexpr inline T1 DivCeil(T1 a, T2 b) {
55
1.10M
  return (a + b - 1) / b;
56
1.10M
}
57
58
template <typename T1, typename T2>
59
20.3k
constexpr inline T1 RoundUpTo(T1 a, T2 b) {
60
20.3k
  return DivCeil(a, b) * b;
61
20.3k
}
unsigned long jpegli::RoundUpTo<unsigned long, unsigned long>(unsigned long, unsigned long)
Line
Count
Source
59
17.3k
constexpr inline T1 RoundUpTo(T1 a, T2 b) {
60
17.3k
  return DivCeil(a, b) * b;
61
17.3k
}
unsigned long jpegli::RoundUpTo<unsigned long, int>(unsigned long, int)
Line
Count
Source
59
2.96k
constexpr inline T1 RoundUpTo(T1 a, T2 b) {
60
2.96k
  return DivCeil(a, b) * b;
61
2.96k
}
62
63
constexpr size_t kDCTBlockSize = 64;
64
// This is set to the same value as MAX_COMPS_IN_SCAN, because that is the
65
// maximum number of channels the libjpeg-turbo decoder can decode.
66
constexpr int kMaxComponents = 4;
67
constexpr int kMaxQuantTables = 4;
68
constexpr int kJpegPrecision = 8;
69
constexpr int kMaxHuffmanTables = 4;
70
constexpr size_t kJpegHuffmanMaxBitLength = 16;
71
constexpr int kJpegHuffmanAlphabetSize = 256;
72
constexpr int kJpegDCAlphabetSize = 12;
73
constexpr int kMaxDHTMarkers = 512;
74
constexpr int kMaxDimPixels = 65535;
75
constexpr uint8_t kApp1 = 0xE1;
76
constexpr uint8_t kApp2 = 0xE2;
77
const uint8_t kIccProfileTag[12] = "ICC_PROFILE";
78
const uint8_t kExifTag[6] = "Exif\0";
79
const uint8_t kXMPTag[29] = "http://ns.adobe.com/xap/1.0/";
80
81
/* clang-format off */
82
constexpr uint32_t kJPEGNaturalOrder[80] = {
83
  0,   1,  8, 16,  9,  2,  3, 10,
84
  17, 24, 32, 25, 18, 11,  4,  5,
85
  12, 19, 26, 33, 40, 48, 41, 34,
86
  27, 20, 13,  6,  7, 14, 21, 28,
87
  35, 42, 49, 56, 57, 50, 43, 36,
88
  29, 22, 15, 23, 30, 37, 44, 51,
89
  58, 59, 52, 45, 38, 31, 39, 46,
90
  53, 60, 61, 54, 47, 55, 62, 63,
91
  // extra entries for safety in decoder
92
  63, 63, 63, 63, 63, 63, 63, 63,
93
  63, 63, 63, 63, 63, 63, 63, 63
94
};
95
96
constexpr uint32_t kJPEGZigZagOrder[64] = {
97
  0,   1,  5,  6, 14, 15, 27, 28,
98
  2,   4,  7, 13, 16, 26, 29, 42,
99
  3,   8, 12, 17, 25, 30, 41, 43,
100
  9,  11, 18, 24, 31, 40, 44, 53,
101
  10, 19, 23, 32, 39, 45, 52, 54,
102
  20, 22, 33, 38, 46, 51, 55, 60,
103
  21, 34, 37, 47, 50, 56, 59, 61,
104
  35, 36, 48, 49, 57, 58, 62, 63
105
};
106
/* clang-format on */
107
108
template <typename T>
109
class RowBuffer {
110
 public:
111
  template <typename CInfoType>
112
11.3k
  void Allocate(CInfoType cinfo, size_t num_rows, size_t rowsize) {
113
11.3k
    static_assert(sizeof(T) == 4);
114
11.3k
    size_t vec_size = std::max(VectorSize(), sizeof(T));
115
11.3k
    size_t alignment = std::max<size_t>(HWY_ALIGNMENT, vec_size);
116
11.3k
    size_t min_memstride = alignment + rowsize * sizeof(T) + vec_size;
117
11.3k
    size_t memstride = RoundUpTo(min_memstride, alignment);
118
11.3k
    xsize_ = rowsize;
119
11.3k
    ysize_ = num_rows;
120
11.3k
    stride_ = memstride / sizeof(T);
121
11.3k
    offset_ = alignment / sizeof(T);
122
11.3k
    data_ = ::jpegli::Allocate<T>(cinfo, ysize_ * stride_, JPOOL_IMAGE_ALIGNED);
123
11.3k
  }
124
125
177M
  T* Row(ssize_t y) const {
126
177M
    return &data_[((ysize_ + y) % ysize_) * stride_ + offset_];
127
177M
  }
128
129
  size_t xsize() const { return xsize_; };
130
  size_t ysize() const { return ysize_; };
131
30.0M
  size_t stride() const { return stride_; }
132
133
  void PadRow(size_t y, size_t from, int border) {
134
    float* row = Row(y);
135
    for (int offset = -border; offset < 0; ++offset) {
136
      row[offset] = row[0];
137
    }
138
    float last_val = row[from - 1];
139
    for (size_t x = from; x < xsize_ + border; ++x) {
140
      row[x] = last_val;
141
    }
142
  }
143
144
  void CopyRow(ssize_t dst_row, ssize_t src_row, int border) {
145
    memcpy(Row(dst_row) - border, Row(src_row) - border,
146
           (xsize_ + 2 * border) * sizeof(T));
147
  }
148
149
  void FillRow(ssize_t y, T val, size_t len) {
150
    T* row = Row(y);
151
    for (size_t x = 0; x < len; ++x) {
152
      row[x] = val;
153
    }
154
  }
155
156
 private:
157
  size_t xsize_;
158
  size_t ysize_;
159
  size_t stride_;
160
  size_t offset_;
161
  T* data_;
162
};
163
164
}  // namespace jpegli
165
166
#endif  // LIB_JPEGLI_COMMON_INTERNAL_H_