Coverage Report

Created: 2024-09-08 07:14

/src/libjxl/lib/jxl/image_ops.h
Line
Count
Source (jump to first uncovered line)
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_JXL_IMAGE_OPS_H_
7
#define LIB_JXL_IMAGE_OPS_H_
8
9
// Operations on images.
10
11
#include <jxl/memory_manager.h>
12
13
#include <algorithm>
14
#include <cstddef>
15
#include <cstdint>
16
#include <limits>
17
18
#include "lib/jxl/base/compiler_specific.h"
19
#include "lib/jxl/base/rect.h"
20
#include "lib/jxl/base/status.h"
21
#include "lib/jxl/frame_dimensions.h"
22
#include "lib/jxl/image.h"
23
24
namespace jxl {
25
26
// Works for mixed image-like argument types.
27
template <class Image1, class Image2>
28
587k
bool SameSize(const Image1& image1, const Image2& image2) {
29
587k
  return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize();
30
587k
}
bool jxl::SameSize<jxl::RectT<unsigned long>, jxl::RectT<unsigned long> >(jxl::RectT<unsigned long> const&, jxl::RectT<unsigned long> const&)
Line
Count
Source
28
209k
bool SameSize(const Image1& image1, const Image2& image2) {
29
209k
  return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize();
30
209k
}
bool jxl::SameSize<jxl::Plane<int>, jxl::Plane<int> >(jxl::Plane<int> const&, jxl::Plane<int> const&)
Line
Count
Source
28
180
bool SameSize(const Image1& image1, const Image2& image2) {
29
180
  return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize();
30
180
}
Unexecuted instantiation: bool jxl::SameSize<jxl::Plane<int>, jxl::Plane<float> >(jxl::Plane<int> const&, jxl::Plane<float> const&)
Unexecuted instantiation: bool jxl::SameSize<jxl::RectT<unsigned long>, jxl::Image3<float> >(jxl::RectT<unsigned long> const&, jxl::Image3<float> const&)
bool jxl::SameSize<jxl::RectT<unsigned long>, jxl::Plane<float> >(jxl::RectT<unsigned long> const&, jxl::Plane<float> const&)
Line
Count
Source
28
376k
bool SameSize(const Image1& image1, const Image2& image2) {
29
376k
  return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize();
30
376k
}
bool jxl::SameSize<jxl::Plane<float>, jxl::Plane<float> >(jxl::Plane<float> const&, jxl::Plane<float> const&)
Line
Count
Source
28
472
bool SameSize(const Image1& image1, const Image2& image2) {
29
472
  return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize();
30
472
}
Unexecuted instantiation: bool jxl::SameSize<jxl::Image3<float>, jxl::Plane<float> >(jxl::Image3<float> const&, jxl::Plane<float> const&)
Unexecuted instantiation: bool jxl::SameSize<jxl::Image3<float>, jxl::Image3<float> >(jxl::Image3<float> const&, jxl::Image3<float> const&)
Unexecuted instantiation: bool jxl::SameSize<jxl::ImageBundle, jxl::ImageBundle>(jxl::ImageBundle const&, jxl::ImageBundle const&)
31
32
template <typename T>
33
652
Status CopyImageTo(const Plane<T>& from, Plane<T>* JXL_RESTRICT to) {
34
652
  JXL_ENSURE(SameSize(from, *to));
35
652
  if (from.ysize() == 0 || from.xsize() == 0) return true;
36
18.7k
  for (size_t y = 0; y < from.ysize(); ++y) {
37
18.0k
    const T* JXL_RESTRICT row_from = from.ConstRow(y);
38
18.0k
    T* JXL_RESTRICT row_to = to->Row(y);
39
18.0k
    memcpy(row_to, row_from, from.xsize() * sizeof(T));
40
18.0k
  }
41
644
  return true;
42
652
}
Unexecuted instantiation: jxl::Status jxl::CopyImageTo<float>(jxl::Plane<float> const&, jxl::Plane<float>*)
jxl::Status jxl::CopyImageTo<int>(jxl::Plane<int> const&, jxl::Plane<int>*)
Line
Count
Source
33
180
Status CopyImageTo(const Plane<T>& from, Plane<T>* JXL_RESTRICT to) {
34
180
  JXL_ENSURE(SameSize(from, *to));
35
180
  if (from.ysize() == 0 || from.xsize() == 0) return true;
36
10.0k
  for (size_t y = 0; y < from.ysize(); ++y) {
37
9.82k
    const T* JXL_RESTRICT row_from = from.ConstRow(y);
38
9.82k
    T* JXL_RESTRICT row_to = to->Row(y);
39
9.82k
    memcpy(row_to, row_from, from.xsize() * sizeof(T));
40
9.82k
  }
41
172
  return true;
42
180
}
jxl::Status jxl::CopyImageTo<float>(jxl::Plane<float> const&, jxl::Plane<float>*)
Line
Count
Source
33
472
Status CopyImageTo(const Plane<T>& from, Plane<T>* JXL_RESTRICT to) {
34
472
  JXL_ENSURE(SameSize(from, *to));
35
472
  if (from.ysize() == 0 || from.xsize() == 0) return true;
36
8.72k
  for (size_t y = 0; y < from.ysize(); ++y) {
37
8.25k
    const T* JXL_RESTRICT row_from = from.ConstRow(y);
38
8.25k
    T* JXL_RESTRICT row_to = to->Row(y);
39
8.25k
    memcpy(row_to, row_from, from.xsize() * sizeof(T));
40
8.25k
  }
41
472
  return true;
42
472
}
43
44
// Copies `from:rect_from` to `to:rect_to`.
45
template <typename T>
46
Status CopyImageTo(const Rect& rect_from, const Plane<T>& from,
47
190k
                   const Rect& rect_to, Plane<T>* JXL_RESTRICT to) {
48
190k
  JXL_ENSURE(SameSize(rect_from, rect_to));
49
190k
  JXL_ENSURE(rect_from.IsInside(from));
50
190k
  JXL_ENSURE(rect_to.IsInside(*to));
51
190k
  if (rect_from.xsize() == 0) return true;
52
3.27M
  for (size_t y = 0; y < rect_from.ysize(); ++y) {
53
3.11M
    const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y);
54
3.11M
    T* JXL_RESTRICT row_to = rect_to.Row(to, y);
55
3.11M
    memcpy(row_to, row_from, rect_from.xsize() * sizeof(T));
56
3.11M
  }
57
166k
  return true;
58
190k
}
jxl::Status jxl::CopyImageTo<float>(jxl::RectT<unsigned long> const&, jxl::Plane<float> const&, jxl::RectT<unsigned long> const&, jxl::Plane<float>*)
Line
Count
Source
47
181k
                   const Rect& rect_to, Plane<T>* JXL_RESTRICT to) {
48
181k
  JXL_ENSURE(SameSize(rect_from, rect_to));
49
181k
  JXL_ENSURE(rect_from.IsInside(from));
50
181k
  JXL_ENSURE(rect_to.IsInside(*to));
51
181k
  if (rect_from.xsize() == 0) return true;
52
2.82M
  for (size_t y = 0; y < rect_from.ysize(); ++y) {
53
2.66M
    const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y);
54
2.66M
    T* JXL_RESTRICT row_to = rect_to.Row(to, y);
55
2.66M
    memcpy(row_to, row_from, rect_from.xsize() * sizeof(T));
56
2.66M
  }
57
157k
  return true;
58
181k
}
jxl::Status jxl::CopyImageTo<int>(jxl::RectT<unsigned long> const&, jxl::Plane<int> const&, jxl::RectT<unsigned long> const&, jxl::Plane<int>*)
Line
Count
Source
47
8.78k
                   const Rect& rect_to, Plane<T>* JXL_RESTRICT to) {
48
8.78k
  JXL_ENSURE(SameSize(rect_from, rect_to));
49
8.78k
  JXL_ENSURE(rect_from.IsInside(from));
50
8.78k
  JXL_ENSURE(rect_to.IsInside(*to));
51
8.78k
  if (rect_from.xsize() == 0) return true;
52
455k
  for (size_t y = 0; y < rect_from.ysize(); ++y) {
53
446k
    const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y);
54
446k
    T* JXL_RESTRICT row_to = rect_to.Row(to, y);
55
446k
    memcpy(row_to, row_from, rect_from.xsize() * sizeof(T));
56
446k
  }
57
8.78k
  return true;
58
8.78k
}
59
60
// Copies `from:rect_from` to `to:rect_to`.
61
template <typename T>
62
Status CopyImageTo(const Rect& rect_from, const Image3<T>& from,
63
238
                   const Rect& rect_to, Image3<T>* JXL_RESTRICT to) {
64
238
  JXL_ENSURE(SameSize(rect_from, rect_to));
65
952
  for (size_t c = 0; c < 3; c++) {
66
714
    JXL_RETURN_IF_ERROR(
67
714
        CopyImageTo(rect_from, from.Plane(c), rect_to, &to->Plane(c)));
68
714
  }
69
238
  return true;
70
238
}
Unexecuted instantiation: jxl::Status jxl::CopyImageTo<float>(jxl::RectT<unsigned long> const&, jxl::Image3<float> const&, jxl::RectT<unsigned long> const&, jxl::Image3<float>*)
jxl::Status jxl::CopyImageTo<float>(jxl::RectT<unsigned long> const&, jxl::Image3<float> const&, jxl::RectT<unsigned long> const&, jxl::Image3<float>*)
Line
Count
Source
63
238
                   const Rect& rect_to, Image3<T>* JXL_RESTRICT to) {
64
238
  JXL_ENSURE(SameSize(rect_from, rect_to));
65
952
  for (size_t c = 0; c < 3; c++) {
66
714
    JXL_RETURN_IF_ERROR(
67
714
        CopyImageTo(rect_from, from.Plane(c), rect_to, &to->Plane(c)));
68
714
  }
69
238
  return true;
70
238
}
71
72
template <typename T, typename U>
73
Status ConvertPlaneAndClamp(const Rect& rect_from, const Plane<T>& from,
74
18.8k
                            const Rect& rect_to, Plane<U>* JXL_RESTRICT to) {
75
18.8k
  JXL_ENSURE(SameSize(rect_from, rect_to));
76
18.8k
  using M = decltype(T() + U());
77
91.3k
  for (size_t y = 0; y < rect_to.ysize(); ++y) {
78
72.4k
    const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y);
79
72.4k
    U* JXL_RESTRICT row_to = rect_to.Row(to, y);
80
248k
    for (size_t x = 0; x < rect_to.xsize(); ++x) {
81
175k
      row_to[x] =
82
175k
          std::min<M>(std::max<M>(row_from[x], std::numeric_limits<U>::min()),
83
175k
                      std::numeric_limits<U>::max());
84
175k
    }
85
72.4k
  }
86
18.8k
  return true;
87
18.8k
}
jxl::Status jxl::ConvertPlaneAndClamp<int, signed char>(jxl::RectT<unsigned long> const&, jxl::Plane<int> const&, jxl::RectT<unsigned long> const&, jxl::Plane<signed char>*)
Line
Count
Source
74
18.3k
                            const Rect& rect_to, Plane<U>* JXL_RESTRICT to) {
75
18.3k
  JXL_ENSURE(SameSize(rect_from, rect_to));
76
18.3k
  using M = decltype(T() + U());
77
90.3k
  for (size_t y = 0; y < rect_to.ysize(); ++y) {
78
72.0k
    const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y);
79
72.0k
    U* JXL_RESTRICT row_to = rect_to.Row(to, y);
80
247k
    for (size_t x = 0; x < rect_to.xsize(); ++x) {
81
175k
      row_to[x] =
82
175k
          std::min<M>(std::max<M>(row_from[x], std::numeric_limits<U>::min()),
83
175k
                      std::numeric_limits<U>::max());
84
175k
    }
85
72.0k
  }
86
18.3k
  return true;
87
18.3k
}
jxl::Status jxl::ConvertPlaneAndClamp<signed char, int>(jxl::RectT<unsigned long> const&, jxl::Plane<signed char> const&, jxl::RectT<unsigned long> const&, jxl::Plane<int>*)
Line
Count
Source
74
476
                            const Rect& rect_to, Plane<U>* JXL_RESTRICT to) {
75
476
  JXL_ENSURE(SameSize(rect_from, rect_to));
76
476
  using M = decltype(T() + U());
77
952
  for (size_t y = 0; y < rect_to.ysize(); ++y) {
78
476
    const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y);
79
476
    U* JXL_RESTRICT row_to = rect_to.Row(to, y);
80
952
    for (size_t x = 0; x < rect_to.xsize(); ++x) {
81
476
      row_to[x] =
82
476
          std::min<M>(std::max<M>(row_from[x], std::numeric_limits<U>::min()),
83
476
                      std::numeric_limits<U>::max());
84
476
    }
85
476
  }
86
476
  return true;
87
476
}
88
89
// Copies `from` to `to`.
90
template <typename T>
91
0
Status CopyImageTo(const T& from, T* JXL_RESTRICT to) {
92
0
  return CopyImageTo(Rect(from), from, Rect(*to), to);
93
0
}
94
95
// Copies `from:rect_from` to `to:rect_to`; also copies `padding` pixels of
96
// border around `from:rect_from`, in all directions, whenever they are inside
97
// the first image.
98
template <typename T>
99
Status CopyImageToWithPadding(const Rect& from_rect, const T& from,
100
0
                              size_t padding, const Rect& to_rect, T* to) {
101
0
  size_t xextra0 = std::min(padding, from_rect.x0());
102
0
  size_t xextra1 =
103
0
      std::min(padding, from.xsize() - from_rect.x0() - from_rect.xsize());
104
0
  size_t yextra0 = std::min(padding, from_rect.y0());
105
0
  size_t yextra1 =
106
0
      std::min(padding, from.ysize() - from_rect.y0() - from_rect.ysize());
107
0
  JXL_ENSURE(to_rect.x0() >= xextra0);
108
0
  JXL_ENSURE(to_rect.y0() >= yextra0);
109
110
0
  return CopyImageTo(Rect(from_rect.x0() - xextra0, from_rect.y0() - yextra0,
111
0
                          from_rect.xsize() + xextra0 + xextra1,
112
0
                          from_rect.ysize() + yextra0 + yextra1),
113
0
                     from,
114
0
                     Rect(to_rect.x0() - xextra0, to_rect.y0() - yextra0,
115
0
                          to_rect.xsize() + xextra0 + xextra1,
116
0
                          to_rect.ysize() + yextra0 + yextra1),
117
0
                     to);
118
0
}
119
120
// Returns linear combination of two grayscale images.
121
template <typename T>
122
StatusOr<Plane<T>> LinComb(const T lambda1, const Plane<T>& image1,
123
0
                           const T lambda2, const Plane<T>& image2) {
124
0
  const size_t xsize = image1.xsize();
125
0
  const size_t ysize = image1.ysize();
126
0
  JXL_ENSURE(xsize == image2.xsize());
127
0
  JXL_ENSURE(ysize == image2.ysize());
128
0
  JxlMemoryManager* memory_manager = image1.memory_manager();
129
0
  JXL_ASSIGN_OR_RETURN(Plane<T> out,
130
0
                       Plane<T>::Create(memory_manager, xsize, ysize));
131
0
  for (size_t y = 0; y < ysize; ++y) {
132
0
    const T* const JXL_RESTRICT row1 = image1.Row(y);
133
0
    const T* const JXL_RESTRICT row2 = image2.Row(y);
134
0
    T* const JXL_RESTRICT row_out = out.Row(y);
135
0
    for (size_t x = 0; x < xsize; ++x) {
136
0
      row_out[x] = lambda1 * row1[x] + lambda2 * row2[x];
137
0
    }
138
0
  }
139
0
  return out;
140
0
}
141
142
// Multiplies image by lambda in-place
143
template <typename T>
144
0
void ScaleImage(const T lambda, Plane<T>* image) {
145
0
  for (size_t y = 0; y < image->ysize(); ++y) {
146
0
    T* const JXL_RESTRICT row = image->Row(y);
147
0
    for (size_t x = 0; x < image->xsize(); ++x) {
148
0
      row[x] = lambda * row[x];
149
0
    }
150
0
  }
151
0
}
152
153
// Multiplies image by lambda in-place
154
template <typename T>
155
void ScaleImage(const T lambda, Image3<T>* image) {
156
  for (size_t c = 0; c < 3; ++c) {
157
    ScaleImage(lambda, &image->Plane(c));
158
  }
159
}
160
161
template <typename T>
162
32.2k
void FillImage(const T value, Plane<T>* image) {
163
667k
  for (size_t y = 0; y < image->ysize(); ++y) {
164
635k
    T* const JXL_RESTRICT row = image->Row(y);
165
40.3M
    for (size_t x = 0; x < image->xsize(); ++x) {
166
39.6M
      row[x] = value;
167
39.6M
    }
168
635k
  }
169
32.2k
}
void jxl::FillImage<unsigned char>(unsigned char, jxl::Plane<unsigned char>*)
Line
Count
Source
162
10.3k
void FillImage(const T value, Plane<T>* image) {
163
326k
  for (size_t y = 0; y < image->ysize(); ++y) {
164
315k
    T* const JXL_RESTRICT row = image->Row(y);
165
6.23M
    for (size_t x = 0; x < image->xsize(); ++x) {
166
5.91M
      row[x] = value;
167
5.91M
    }
168
315k
  }
169
10.3k
}
Unexecuted instantiation: void jxl::FillImage<int>(int, jxl::Plane<int>*)
void jxl::FillImage<float>(float, jxl::Plane<float>*)
Line
Count
Source
162
21.8k
void FillImage(const T value, Plane<T>* image) {
163
341k
  for (size_t y = 0; y < image->ysize(); ++y) {
164
319k
    T* const JXL_RESTRICT row = image->Row(y);
165
34.0M
    for (size_t x = 0; x < image->xsize(); ++x) {
166
33.7M
      row[x] = value;
167
33.7M
    }
168
319k
  }
169
21.8k
}
170
171
template <typename T>
172
3.86M
void ZeroFillImage(Plane<T>* image) {
173
3.86M
  if (image->xsize() == 0) return;
174
4.32M
  for (size_t y = 0; y < image->ysize(); ++y) {
175
4.16M
    T* const JXL_RESTRICT row = image->Row(y);
176
4.16M
    memset(row, 0, image->xsize() * sizeof(T));
177
4.16M
  }
178
159k
}
void jxl::ZeroFillImage<int>(jxl::Plane<int>*)
Line
Count
Source
172
3.76M
void ZeroFillImage(Plane<T>* image) {
173
3.76M
  if (image->xsize() == 0) return;
174
2.90M
  for (size_t y = 0; y < image->ysize(); ++y) {
175
2.84M
    T* const JXL_RESTRICT row = image->Row(y);
176
2.84M
    memset(row, 0, image->xsize() * sizeof(T));
177
2.84M
  }
178
59.7k
}
Unexecuted instantiation: void jxl::ZeroFillImage<short>(jxl::Plane<short>*)
void jxl::ZeroFillImage<unsigned char>(jxl::Plane<unsigned char>*)
Line
Count
Source
172
288
void ZeroFillImage(Plane<T>* image) {
173
288
  if (image->xsize() == 0) return;
174
3.24k
  for (size_t y = 0; y < image->ysize(); ++y) {
175
2.95k
    T* const JXL_RESTRICT row = image->Row(y);
176
2.95k
    memset(row, 0, image->xsize() * sizeof(T));
177
2.95k
  }
178
288
}
void jxl::ZeroFillImage<signed char>(jxl::Plane<signed char>*)
Line
Count
Source
172
99.5k
void ZeroFillImage(Plane<T>* image) {
173
99.5k
  if (image->xsize() == 0) return;
174
1.42M
  for (size_t y = 0; y < image->ysize(); ++y) {
175
1.32M
    T* const JXL_RESTRICT row = image->Row(y);
176
1.32M
    memset(row, 0, image->xsize() * sizeof(T));
177
1.32M
  }
178
99.5k
}
Unexecuted instantiation: void jxl::ZeroFillImage<float>(jxl::Plane<float>*)
179
180
// Mirrors out of bounds coordinates and returns valid coordinates unchanged.
181
// We assume the radius (distance outside the image) is small compared to the
182
// image size, otherwise this might not terminate.
183
// The mirror is outside the last column (border pixel is also replicated).
184
23.1M
static inline int64_t Mirror(int64_t x, const int64_t xsize) {
185
23.1M
  JXL_DASSERT(xsize != 0);
186
187
  // TODO(janwas): replace with branchless version
188
49.0M
  while (x < 0 || x >= xsize) {
189
25.9M
    if (x < 0) {
190
13.0M
      x = -x - 1;
191
13.0M
    } else {
192
12.9M
      x = 2 * xsize - 1 - x;
193
12.9M
    }
194
25.9M
  }
195
23.1M
  return x;
196
23.1M
}
Unexecuted instantiation: decode.cc:jxl::Mirror(long, long)
Unexecuted instantiation: image_metadata.cc:jxl::Mirror(long, long)
Unexecuted instantiation: encoding.cc:jxl::Mirror(long, long)
Unexecuted instantiation: modular_image.cc:jxl::Mirror(long, long)
Unexecuted instantiation: transform.cc:jxl::Mirror(long, long)
Unexecuted instantiation: quant_weights.cc:jxl::Mirror(long, long)
Unexecuted instantiation: quantizer.cc:jxl::Mirror(long, long)
Unexecuted instantiation: decode_to_jpeg.cc:jxl::Mirror(long, long)
Unexecuted instantiation: dec_frame.cc:jxl::Mirror(long, long)
Unexecuted instantiation: dec_group.cc:jxl::Mirror(long, long)
Unexecuted instantiation: dec_modular.cc:jxl::Mirror(long, long)
Unexecuted instantiation: dec_noise.cc:jxl::Mirror(long, long)
Unexecuted instantiation: dec_patch_dictionary.cc:jxl::Mirror(long, long)
Unexecuted instantiation: dec_xyb.cc:jxl::Mirror(long, long)
Unexecuted instantiation: epf.cc:jxl::Mirror(long, long)
Unexecuted instantiation: palette.cc:jxl::Mirror(long, long)
Unexecuted instantiation: rct.cc:jxl::Mirror(long, long)
Unexecuted instantiation: squeeze.cc:jxl::Mirror(long, long)
Unexecuted instantiation: passes_state.cc:jxl::Mirror(long, long)
Unexecuted instantiation: simple_render_pipeline.cc:jxl::Mirror(long, long)
Unexecuted instantiation: ac_strategy.cc:jxl::Mirror(long, long)
Unexecuted instantiation: blending.cc:jxl::Mirror(long, long)
Unexecuted instantiation: chroma_from_luma.cc:jxl::Mirror(long, long)
Unexecuted instantiation: coeff_order.cc:jxl::Mirror(long, long)
Unexecuted instantiation: dec_cache.cc:jxl::Mirror(long, long)
low_memory_render_pipeline.cc:jxl::Mirror(long, long)
Line
Count
Source
184
22.1M
static inline int64_t Mirror(int64_t x, const int64_t xsize) {
185
22.1M
  JXL_DASSERT(xsize != 0);
186
187
  // TODO(janwas): replace with branchless version
188
47.7M
  while (x < 0 || x >= xsize) {
189
25.6M
    if (x < 0) {
190
12.8M
      x = -x - 1;
191
12.8M
    } else {
192
12.8M
      x = 2 * xsize - 1 - x;
193
12.8M
    }
194
25.6M
  }
195
22.1M
  return x;
196
22.1M
}
Unexecuted instantiation: stage_blending.cc:jxl::Mirror(long, long)
Unexecuted instantiation: stage_epf.cc:jxl::Mirror(long, long)
Unexecuted instantiation: stage_patches.cc:jxl::Mirror(long, long)
Unexecuted instantiation: stage_write.cc:jxl::Mirror(long, long)
Unexecuted instantiation: image_bundle.cc:jxl::Mirror(long, long)
Unexecuted instantiation: encode.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_jpeg_data.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_fields.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_frame.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_group.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_heuristics.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_modular.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_patch_dictionary.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_progressive_split.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_quant_weights.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_toc.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_xyb.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_encoding.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_ma.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_transform.cc:jxl::Mirror(long, long)
Unexecuted instantiation: dec_external_image.cc:jxl::Mirror(long, long)
Unexecuted instantiation: image_ops.cc:jxl::Mirror(long, long)
Unexecuted instantiation: butteraugli.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_ac_strategy.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_adaptive_quantization.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_ans.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_butteraugli_comparator.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_cache.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_chroma_from_luma.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_coeff_order.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_debug_image.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_dot_dictionary.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_entropy_coder.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_external_image.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_gaborish.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_image_bundle.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_palette.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_rct.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_squeeze.cc:jxl::Mirror(long, long)
Unexecuted instantiation: convolve_separable5.cc:jxl::Mirror(long, long)
Unexecuted instantiation: convolve_slow.cc:jxl::Mirror(long, long)
convolve_symmetric5.cc:jxl::Mirror(long, long)
Line
Count
Source
184
1.01M
static inline int64_t Mirror(int64_t x, const int64_t xsize) {
185
1.01M
  JXL_DASSERT(xsize != 0);
186
187
  // TODO(janwas): replace with branchless version
188
1.24M
  while (x < 0 || x >= xsize) {
189
231k
    if (x < 0) {
190
126k
      x = -x - 1;
191
126k
    } else {
192
105k
      x = 2 * xsize - 1 - x;
193
105k
    }
194
231k
  }
195
1.01M
  return x;
196
1.01M
}
Unexecuted instantiation: enc_detect_dots.cc:jxl::Mirror(long, long)
Unexecuted instantiation: set_from_bytes_fuzzer.cc:jxl::Mirror(long, long)
Unexecuted instantiation: codec.cc:jxl::Mirror(long, long)
Unexecuted instantiation: packed_image_convert.cc:jxl::Mirror(long, long)
Unexecuted instantiation: jpg.cc:jxl::Mirror(long, long)
Unexecuted instantiation: test_image.cc:jxl::Mirror(long, long)
Unexecuted instantiation: test_utils.cc:jxl::Mirror(long, long)
Unexecuted instantiation: metrics.cc:jxl::Mirror(long, long)
Unexecuted instantiation: enc_comparator.cc:jxl::Mirror(long, long)
Unexecuted instantiation: transforms_fuzzer.cc:jxl::Mirror(long, long)
Unexecuted instantiation: fields_fuzzer.cc:jxl::Mirror(long, long)
197
198
// Wrap modes for ensuring X/Y coordinates are in the valid range [0, size):
199
200
// Mirrors (repeating the edge pixel once). Useful for convolutions.
201
struct WrapMirror {
202
1.01M
  JXL_INLINE int64_t operator()(const int64_t coord, const int64_t size) const {
203
1.01M
    return Mirror(coord, size);
204
1.01M
  }
205
};
206
207
// Returns the same coordinate: required for TFNode with Border(), or useful
208
// when we know "coord" is already valid (e.g. interior of an image).
209
struct WrapUnchanged {
210
115k
  JXL_INLINE int64_t operator()(const int64_t coord, int64_t /*size*/) const {
211
115k
    return coord;
212
115k
  }
213
};
214
215
// Similar to Wrap* but for row pointers (reduces Row() multiplications).
216
217
class WrapRowMirror {
218
 public:
219
  template <class ImageOrView>
220
  WrapRowMirror(const ImageOrView& image, size_t ysize)
221
0
      : first_row_(image.ConstRow(0)), last_row_(image.ConstRow(ysize - 1)) {}
222
223
  const float* operator()(const float* const JXL_RESTRICT row,
224
0
                          const int64_t stride) const {
225
0
    if (row < first_row_) {
226
0
      const int64_t num_before = first_row_ - row;
227
0
      // Mirrored; one row before => row 0, two before = row 1, ...
228
0
      return first_row_ + num_before - stride;
229
0
    }
230
0
    if (row > last_row_) {
231
0
      const int64_t num_after = row - last_row_;
232
0
      // Mirrored; one row after => last row, two after = last - 1, ...
233
0
      return last_row_ - num_after + stride;
234
0
    }
235
0
    return row;
236
0
  }
237
238
 private:
239
  const float* const JXL_RESTRICT first_row_;
240
  const float* const JXL_RESTRICT last_row_;
241
};
242
243
struct WrapRowUnchanged {
244
  JXL_INLINE const float* operator()(const float* const JXL_RESTRICT row,
245
0
                                     int64_t /*stride*/) const {
246
0
    return row;
247
0
  }
248
};
249
250
// Computes the minimum and maximum pixel value.
251
template <typename T>
252
void ImageMinMax(const Plane<T>& image, T* const JXL_RESTRICT min,
253
0
                 T* const JXL_RESTRICT max) {
254
0
  *min = std::numeric_limits<T>::max();
255
0
  *max = std::numeric_limits<T>::lowest();
256
0
  for (size_t y = 0; y < image.ysize(); ++y) {
257
0
    const T* const JXL_RESTRICT row = image.Row(y);
258
0
    for (size_t x = 0; x < image.xsize(); ++x) {
259
0
      *min = std::min(*min, row[x]);
260
0
      *max = std::max(*max, row[x]);
261
0
    }
262
0
  }
263
0
}
Unexecuted instantiation: void jxl::ImageMinMax<float>(jxl::Plane<float> const&, float*, float*)
Unexecuted instantiation: void jxl::ImageMinMax<unsigned char>(jxl::Plane<unsigned char> const&, unsigned char*, unsigned char*)
264
265
// Initializes all planes to the same "value".
266
template <typename T>
267
void FillImage(const T value, Image3<T>* image) {
268
  for (size_t c = 0; c < 3; ++c) {
269
    for (size_t y = 0; y < image->ysize(); ++y) {
270
      T* JXL_RESTRICT row = image->PlaneRow(c, y);
271
      for (size_t x = 0; x < image->xsize(); ++x) {
272
        row[x] = value;
273
      }
274
    }
275
  }
276
}
277
278
template <typename T>
279
952
void FillPlane(const T value, Plane<T>* image, Rect rect) {
280
1.90k
  for (size_t y = 0; y < rect.ysize(); ++y) {
281
952
    T* JXL_RESTRICT row = rect.Row(image, y);
282
1.90k
    for (size_t x = 0; x < rect.xsize(); ++x) {
283
952
      row[x] = value;
284
952
    }
285
952
  }
286
952
}
void jxl::FillPlane<unsigned char>(unsigned char, jxl::Plane<unsigned char>*, jxl::RectT<unsigned long>)
Line
Count
Source
279
952
void FillPlane(const T value, Plane<T>* image, Rect rect) {
280
1.90k
  for (size_t y = 0; y < rect.ysize(); ++y) {
281
952
    T* JXL_RESTRICT row = rect.Row(image, y);
282
1.90k
    for (size_t x = 0; x < rect.xsize(); ++x) {
283
952
      row[x] = value;
284
952
    }
285
952
  }
286
952
}
Unexecuted instantiation: void jxl::FillPlane<float>(float, jxl::Plane<float>*, jxl::RectT<unsigned long>)
287
288
template <typename T>
289
60
void ZeroFillImage(Image3<T>* image) {
290
240
  for (size_t c = 0; c < 3; ++c) {
291
417
    for (size_t y = 0; y < image->ysize(); ++y) {
292
237
      T* JXL_RESTRICT row = image->PlaneRow(c, y);
293
237
      if (image->xsize() != 0) memset(row, 0, image->xsize() * sizeof(T));
294
237
    }
295
180
  }
296
60
}
void jxl::ZeroFillImage<int>(jxl::Image3<int>*)
Line
Count
Source
289
23
void ZeroFillImage(Image3<T>* image) {
290
92
  for (size_t c = 0; c < 3; ++c) {
291
153
    for (size_t y = 0; y < image->ysize(); ++y) {
292
84
      T* JXL_RESTRICT row = image->PlaneRow(c, y);
293
84
      if (image->xsize() != 0) memset(row, 0, image->xsize() * sizeof(T));
294
84
    }
295
69
  }
296
23
}
void jxl::ZeroFillImage<short>(jxl::Image3<short>*)
Line
Count
Source
289
37
void ZeroFillImage(Image3<T>* image) {
290
148
  for (size_t c = 0; c < 3; ++c) {
291
264
    for (size_t y = 0; y < image->ysize(); ++y) {
292
153
      T* JXL_RESTRICT row = image->PlaneRow(c, y);
293
153
      if (image->xsize() != 0) memset(row, 0, image->xsize() * sizeof(T));
294
153
    }
295
111
  }
296
37
}
Unexecuted instantiation: void jxl::ZeroFillImage<float>(jxl::Image3<float>*)
297
298
// Same as above, but operates in-place. Assumes that the `in` image was
299
// allocated large enough.
300
Status PadImageToBlockMultipleInPlace(Image3F* JXL_RESTRICT in,
301
                                      size_t block_dim = kBlockDim);
302
303
// Downsamples an image by a given factor.
304
StatusOr<Image3F> DownsampleImage(const Image3F& opsin, size_t factor);
305
StatusOr<ImageF> DownsampleImage(const ImageF& image, size_t factor);
306
307
}  // namespace jxl
308
309
#endif  // LIB_JXL_IMAGE_OPS_H_