/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/common.h" |
19 | | #include "lib/jxl/base/compiler_specific.h" |
20 | | #include "lib/jxl/base/rect.h" |
21 | | #include "lib/jxl/base/status.h" |
22 | | #include "lib/jxl/frame_dimensions.h" |
23 | | #include "lib/jxl/image.h" |
24 | | |
25 | | namespace jxl { |
26 | | |
27 | | // Works for mixed image-like argument types. |
28 | | template <class Image1, class Image2> |
29 | 337k | bool SameSize(const Image1& image1, const Image2& image2) { |
30 | 337k | return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize(); |
31 | 337k | } bool jxl::SameSize<jxl::RectT<unsigned long>, jxl::RectT<unsigned long> >(jxl::RectT<unsigned long> const&, jxl::RectT<unsigned long> const&) Line | Count | Source | 29 | 155k | bool SameSize(const Image1& image1, const Image2& image2) { | 30 | 155k | return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize(); | 31 | 155k | } |
bool jxl::SameSize<jxl::Plane<float>, jxl::Plane<float> >(jxl::Plane<float> const&, jxl::Plane<float> const&) Line | Count | Source | 29 | 2.32k | bool SameSize(const Image1& image1, const Image2& image2) { | 30 | 2.32k | return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize(); | 31 | 2.32k | } |
Unexecuted instantiation: bool jxl::SameSize<jxl::Plane<int>, jxl::Plane<int> >(jxl::Plane<int> const&, jxl::Plane<int> const&) 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::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::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 | 29 | 178k | bool SameSize(const Image1& image1, const Image2& image2) { | 30 | 178k | return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize(); | 31 | 178k | } |
|
32 | | |
33 | | template <typename T> |
34 | 2.32k | Status CopyImageTo(const Plane<T>& from, Plane<T>* JXL_RESTRICT to) { |
35 | 2.32k | JXL_ENSURE(SameSize(from, *to)); |
36 | 2.32k | if (from.ysize() == 0 || from.xsize() == 0) return true; |
37 | 561k | for (size_t y = 0; y < from.ysize(); ++y) { |
38 | 559k | const T* JXL_RESTRICT row_from = from.ConstRow(y); |
39 | 559k | T* JXL_RESTRICT row_to = to->Row(y); |
40 | 559k | memcpy(row_to, row_from, from.xsize() * sizeof(T)); |
41 | 559k | } |
42 | 2.32k | return true; |
43 | 2.32k | } jxl::Status jxl::CopyImageTo<float>(jxl::Plane<float> const&, jxl::Plane<float>*) Line | Count | Source | 34 | 2.32k | Status CopyImageTo(const Plane<T>& from, Plane<T>* JXL_RESTRICT to) { | 35 | 2.32k | JXL_ENSURE(SameSize(from, *to)); | 36 | 2.32k | if (from.ysize() == 0 || from.xsize() == 0) return true; | 37 | 561k | for (size_t y = 0; y < from.ysize(); ++y) { | 38 | 559k | const T* JXL_RESTRICT row_from = from.ConstRow(y); | 39 | 559k | T* JXL_RESTRICT row_to = to->Row(y); | 40 | 559k | memcpy(row_to, row_from, from.xsize() * sizeof(T)); | 41 | 559k | } | 42 | 2.32k | return true; | 43 | 2.32k | } |
Unexecuted instantiation: jxl::Status jxl::CopyImageTo<int>(jxl::Plane<int> const&, jxl::Plane<int>*) |
44 | | |
45 | | // Copies `from:rect_from` to `to:rect_to`. |
46 | | template <typename T> |
47 | | Status CopyImageTo(const Rect& rect_from, const Plane<T>& from, |
48 | 144k | const Rect& rect_to, Plane<T>* JXL_RESTRICT to) { |
49 | 144k | JXL_ENSURE(SameSize(rect_from, rect_to)); |
50 | 144k | JXL_ENSURE(rect_from.IsInside(from)); |
51 | 144k | JXL_ENSURE(rect_to.IsInside(*to)); |
52 | 144k | if (rect_from.xsize() == 0) return true; |
53 | 14.9M | for (size_t y = 0; y < rect_from.ysize(); ++y) { |
54 | 14.7M | const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y); |
55 | 14.7M | T* JXL_RESTRICT row_to = rect_to.Row(to, y); |
56 | 14.7M | memcpy(row_to, row_from, rect_from.xsize() * sizeof(T)); |
57 | 14.7M | } |
58 | 144k | return true; |
59 | 144k | } 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 | 48 | 144k | const Rect& rect_to, Plane<T>* JXL_RESTRICT to) { | 49 | 144k | JXL_ENSURE(SameSize(rect_from, rect_to)); | 50 | 144k | JXL_ENSURE(rect_from.IsInside(from)); | 51 | 144k | JXL_ENSURE(rect_to.IsInside(*to)); | 52 | 144k | if (rect_from.xsize() == 0) return true; | 53 | 14.8M | for (size_t y = 0; y < rect_from.ysize(); ++y) { | 54 | 14.7M | const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y); | 55 | 14.7M | T* JXL_RESTRICT row_to = rect_to.Row(to, y); | 56 | 14.7M | memcpy(row_to, row_from, rect_from.xsize() * sizeof(T)); | 57 | 14.7M | } | 58 | 143k | return true; | 59 | 144k | } |
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 | 48 | 749 | const Rect& rect_to, Plane<T>* JXL_RESTRICT to) { | 49 | 749 | JXL_ENSURE(SameSize(rect_from, rect_to)); | 50 | 749 | JXL_ENSURE(rect_from.IsInside(from)); | 51 | 749 | JXL_ENSURE(rect_to.IsInside(*to)); | 52 | 749 | if (rect_from.xsize() == 0) return true; | 53 | 55.8k | for (size_t y = 0; y < rect_from.ysize(); ++y) { | 54 | 55.1k | const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y); | 55 | 55.1k | T* JXL_RESTRICT row_to = rect_to.Row(to, y); | 56 | 55.1k | memcpy(row_to, row_from, rect_from.xsize() * sizeof(T)); | 57 | 55.1k | } | 58 | 749 | return true; | 59 | 749 | } |
|
60 | | |
61 | | // Copies `from:rect_from` to `to:rect_to`. |
62 | | template <typename T> |
63 | | Status CopyImageTo(const Rect& rect_from, const Image3<T>& from, |
64 | 2.29k | const Rect& rect_to, Image3<T>* JXL_RESTRICT to) { |
65 | 2.29k | JXL_ENSURE(SameSize(rect_from, rect_to)); |
66 | 9.16k | for (size_t c = 0; c < 3; c++) { |
67 | 6.87k | JXL_RETURN_IF_ERROR( |
68 | 6.87k | CopyImageTo(rect_from, from.Plane(c), rect_to, &to->Plane(c))); |
69 | 6.87k | } |
70 | 2.29k | return true; |
71 | 2.29k | } |
72 | | |
73 | | template <typename T, typename U> |
74 | | Status ConvertPlaneAndClamp(const Rect& rect_from, const Plane<T>& from, |
75 | 8.83k | const Rect& rect_to, Plane<U>* JXL_RESTRICT to) { |
76 | 8.83k | JXL_ENSURE(SameSize(rect_from, rect_to)); |
77 | 8.83k | using M = decltype(T() + U()); |
78 | 34.3k | for (size_t y = 0; y < rect_to.ysize(); ++y) { |
79 | 25.4k | const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y); |
80 | 25.4k | U* JXL_RESTRICT row_to = rect_to.Row(to, y); |
81 | 159k | for (size_t x = 0; x < rect_to.xsize(); ++x) { |
82 | 133k | row_to[x] = jxl::Clamp1<M>(row_from[x], std::numeric_limits<U>::min(), |
83 | 133k | std::numeric_limits<U>::max()); |
84 | 133k | } |
85 | 25.4k | } |
86 | 8.83k | return true; |
87 | 8.83k | } 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 | 75 | 4.58k | const Rect& rect_to, Plane<U>* JXL_RESTRICT to) { | 76 | 4.58k | JXL_ENSURE(SameSize(rect_from, rect_to)); | 77 | 4.58k | using M = decltype(T() + U()); | 78 | 23.6k | for (size_t y = 0; y < rect_to.ysize(); ++y) { | 79 | 19.0k | const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y); | 80 | 19.0k | U* JXL_RESTRICT row_to = rect_to.Row(to, y); | 81 | 133k | for (size_t x = 0; x < rect_to.xsize(); ++x) { | 82 | 114k | row_to[x] = jxl::Clamp1<M>(row_from[x], std::numeric_limits<U>::min(), | 83 | 114k | std::numeric_limits<U>::max()); | 84 | 114k | } | 85 | 19.0k | } | 86 | 4.58k | return true; | 87 | 4.58k | } |
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 | 75 | 4.25k | const Rect& rect_to, Plane<U>* JXL_RESTRICT to) { | 76 | 4.25k | JXL_ENSURE(SameSize(rect_from, rect_to)); | 77 | 4.25k | using M = decltype(T() + U()); | 78 | 10.7k | for (size_t y = 0; y < rect_to.ysize(); ++y) { | 79 | 6.47k | const T* JXL_RESTRICT row_from = rect_from.ConstRow(from, y); | 80 | 6.47k | U* JXL_RESTRICT row_to = rect_to.Row(to, y); | 81 | 25.4k | for (size_t x = 0; x < rect_to.xsize(); ++x) { | 82 | 18.9k | row_to[x] = jxl::Clamp1<M>(row_from[x], std::numeric_limits<U>::min(), | 83 | 18.9k | std::numeric_limits<U>::max()); | 84 | 18.9k | } | 85 | 6.47k | } | 86 | 4.25k | return true; | 87 | 4.25k | } |
|
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 | 54.7k | void FillImage(const T value, Plane<T>* image) { |
163 | 1.16M | for (size_t y = 0; y < image->ysize(); ++y) { |
164 | 1.11M | T* const JXL_RESTRICT row = image->Row(y); |
165 | 39.0M | for (size_t x = 0; x < image->xsize(); ++x) { |
166 | 37.9M | row[x] = value; |
167 | 37.9M | } |
168 | 1.11M | } |
169 | 54.7k | } void jxl::FillImage<unsigned char>(unsigned char, jxl::Plane<unsigned char>*) Line | Count | Source | 162 | 4.11k | void FillImage(const T value, Plane<T>* image) { | 163 | 85.1k | for (size_t y = 0; y < image->ysize(); ++y) { | 164 | 81.0k | T* const JXL_RESTRICT row = image->Row(y); | 165 | 1.13M | for (size_t x = 0; x < image->xsize(); ++x) { | 166 | 1.05M | row[x] = value; | 167 | 1.05M | } | 168 | 81.0k | } | 169 | 4.11k | } |
Unexecuted instantiation: void jxl::FillImage<int>(int, jxl::Plane<int>*) void jxl::FillImage<float>(float, jxl::Plane<float>*) Line | Count | Source | 162 | 50.6k | void FillImage(const T value, Plane<T>* image) { | 163 | 1.08M | for (size_t y = 0; y < image->ysize(); ++y) { | 164 | 1.02M | T* const JXL_RESTRICT row = image->Row(y); | 165 | 37.8M | for (size_t x = 0; x < image->xsize(); ++x) { | 166 | 36.8M | row[x] = value; | 167 | 36.8M | } | 168 | 1.02M | } | 169 | 50.6k | } |
|
170 | | |
171 | | template <typename T> |
172 | 1.49M | void ZeroFillImage(Plane<T>* image) { |
173 | 1.49M | if (image->xsize() == 0) return; |
174 | 3.21M | for (size_t y = 0; y < image->ysize(); ++y) { |
175 | 3.10M | T* const JXL_RESTRICT row = image->Row(y); |
176 | 3.10M | memset(row, 0, image->xsize() * sizeof(T)); |
177 | 3.10M | } |
178 | 107k | } void jxl::ZeroFillImage<int>(jxl::Plane<int>*) Line | Count | Source | 172 | 1.42M | void ZeroFillImage(Plane<T>* image) { | 173 | 1.42M | if (image->xsize() == 0) return; | 174 | 1.31M | for (size_t y = 0; y < image->ysize(); ++y) { | 175 | 1.27M | T* const JXL_RESTRICT row = image->Row(y); | 176 | 1.27M | memset(row, 0, image->xsize() * sizeof(T)); | 177 | 1.27M | } | 178 | 37.9k | } |
Unexecuted instantiation: void jxl::ZeroFillImage<float>(jxl::Plane<float>*) void jxl::ZeroFillImage<unsigned char>(jxl::Plane<unsigned char>*) Line | Count | Source | 172 | 7.24k | void ZeroFillImage(Plane<T>* image) { | 173 | 7.24k | if (image->xsize() == 0) return; | 174 | 1.18M | for (size_t y = 0; y < image->ysize(); ++y) { | 175 | 1.17M | T* const JXL_RESTRICT row = image->Row(y); | 176 | 1.17M | memset(row, 0, image->xsize() * sizeof(T)); | 177 | 1.17M | } | 178 | 7.24k | } |
void jxl::ZeroFillImage<signed char>(jxl::Plane<signed char>*) Line | Count | Source | 172 | 62.8k | void ZeroFillImage(Plane<T>* image) { | 173 | 62.8k | if (image->xsize() == 0) return; | 174 | 719k | for (size_t y = 0; y < image->ysize(); ++y) { | 175 | 656k | T* const JXL_RESTRICT row = image->Row(y); | 176 | 656k | memset(row, 0, image->xsize() * sizeof(T)); | 177 | 656k | } | 178 | 62.8k | } |
Unexecuted instantiation: void jxl::ZeroFillImage<short>(jxl::Plane<short>*) |
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 | 709M | static inline int64_t Mirror(int64_t x, const int64_t xsize) { |
185 | 709M | JXL_DASSERT(xsize != 0); |
186 | | |
187 | | // TODO(janwas): replace with branchless version |
188 | 780M | while (x < 0 || x >= xsize) { |
189 | 71.3M | if (x < 0) { |
190 | 35.7M | x = -x - 1; |
191 | 35.7M | } else { |
192 | 35.6M | x = 2 * xsize - 1 - x; |
193 | 35.6M | } |
194 | 71.3M | } |
195 | 709M | return x; |
196 | 709M | } Unexecuted instantiation: encode.cc:jxl::Mirror(long, long) 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: 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_rct.cc:jxl::Mirror(long, long) Unexecuted instantiation: enc_transform.cc:jxl::Mirror(long, long) Unexecuted instantiation: ac_strategy.cc:jxl::Mirror(long, long) Unexecuted instantiation: chroma_from_luma.cc:jxl::Mirror(long, long) Unexecuted instantiation: dec_cache.cc:jxl::Mirror(long, long) Unexecuted instantiation: dec_external_image.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: image_bundle.cc:jxl::Mirror(long, long) Unexecuted instantiation: image_ops.cc:jxl::Mirror(long, long) Unexecuted instantiation: palette.cc:jxl::Mirror(long, long) Unexecuted instantiation: rct.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: 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: 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_convolve_separable5.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_lz77.cc:jxl::Mirror(long, long) Unexecuted instantiation: enc_palette.cc:jxl::Mirror(long, long) Unexecuted instantiation: blending.cc:jxl::Mirror(long, long) Unexecuted instantiation: coeff_order.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 | 708M | static inline int64_t Mirror(int64_t x, const int64_t xsize) { | 185 | 708M | JXL_DASSERT(xsize != 0); | 186 | | | 187 | | // TODO(janwas): replace with branchless version | 188 | 777M | while (x < 0 || x >= xsize) { | 189 | 69.4M | if (x < 0) { | 190 | 34.7M | x = -x - 1; | 191 | 34.7M | } else { | 192 | 34.7M | x = 2 * xsize - 1 - x; | 193 | 34.7M | } | 194 | 69.4M | } | 195 | 708M | return x; | 196 | 708M | } |
low_memory_render_pipeline.cc:jxl::Mirror(long, long) Line | Count | Source | 184 | 1.53M | static inline int64_t Mirror(int64_t x, const int64_t xsize) { | 185 | 1.53M | JXL_DASSERT(xsize != 0); | 186 | | | 187 | | // TODO(janwas): replace with branchless version | 188 | 3.41M | while (x < 0 || x >= xsize) { | 189 | 1.88M | if (x < 0) { | 190 | 979k | x = -x - 1; | 191 | 979k | } else { | 192 | 905k | x = 2 * xsize - 1 - x; | 193 | 905k | } | 194 | 1.88M | } | 195 | 1.53M | return x; | 196 | 1.53M | } |
Unexecuted instantiation: enc_detect_dots.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 | 708M | JXL_INLINE int64_t operator()(const int64_t coord, const int64_t size) const { |
203 | 708M | return Mirror(coord, size); |
204 | 708M | } |
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 | 657M | JXL_INLINE int64_t operator()(const int64_t coord, int64_t /*size*/) const { |
211 | 657M | return coord; |
212 | 657M | } |
213 | | }; |
214 | | |
215 | | // Computes the minimum and maximum pixel value. |
216 | | template <typename T> |
217 | | void ImageMinMax(const Plane<T>& image, T* const JXL_RESTRICT min, |
218 | 0 | T* const JXL_RESTRICT max) { |
219 | 0 | *min = std::numeric_limits<T>::max(); |
220 | 0 | *max = std::numeric_limits<T>::lowest(); |
221 | 0 | for (size_t y = 0; y < image.ysize(); ++y) { |
222 | 0 | const T* const JXL_RESTRICT row = image.Row(y); |
223 | 0 | for (size_t x = 0; x < image.xsize(); ++x) { |
224 | 0 | *min = std::min(*min, row[x]); |
225 | 0 | *max = std::max(*max, row[x]); |
226 | 0 | } |
227 | 0 | } |
228 | 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*) |
229 | | |
230 | | // Initializes all planes to the same "value". |
231 | | template <typename T> |
232 | | void FillImage(const T value, Image3<T>* image) { |
233 | | for (size_t c = 0; c < 3; ++c) { |
234 | | for (size_t y = 0; y < image->ysize(); ++y) { |
235 | | T* JXL_RESTRICT row = image->PlaneRow(c, y); |
236 | | for (size_t x = 0; x < image->xsize(); ++x) { |
237 | | row[x] = value; |
238 | | } |
239 | | } |
240 | | } |
241 | | } |
242 | | |
243 | | template <typename T> |
244 | 9.16k | void FillPlane(const T value, Plane<T>* image, Rect rect) { |
245 | 287k | for (size_t y = 0; y < rect.ysize(); ++y) { |
246 | 278k | T* JXL_RESTRICT row = rect.Row(image, y); |
247 | 13.1M | for (size_t x = 0; x < rect.xsize(); ++x) { |
248 | 12.8M | row[x] = value; |
249 | 12.8M | } |
250 | 278k | } |
251 | 9.16k | } void jxl::FillPlane<unsigned char>(unsigned char, jxl::Plane<unsigned char>*, jxl::RectT<unsigned long>) Line | Count | Source | 244 | 9.16k | void FillPlane(const T value, Plane<T>* image, Rect rect) { | 245 | 287k | for (size_t y = 0; y < rect.ysize(); ++y) { | 246 | 278k | T* JXL_RESTRICT row = rect.Row(image, y); | 247 | 13.1M | for (size_t x = 0; x < rect.xsize(); ++x) { | 248 | 12.8M | row[x] = value; | 249 | 12.8M | } | 250 | 278k | } | 251 | 9.16k | } |
Unexecuted instantiation: void jxl::FillPlane<float>(float, jxl::Plane<float>*, jxl::RectT<unsigned long>) |
252 | | |
253 | | template <typename T> |
254 | 2.73k | void ZeroFillImage(Image3<T>* image) { |
255 | 10.9k | for (size_t c = 0; c < 3; ++c) { |
256 | 1.63M | for (size_t y = 0; y < image->ysize(); ++y) { |
257 | 1.63M | T* JXL_RESTRICT row = image->PlaneRow(c, y); |
258 | 1.63M | if (image->xsize() != 0) memset(row, 0, image->xsize() * sizeof(T)); |
259 | 1.63M | } |
260 | 8.20k | } |
261 | 2.73k | } void jxl::ZeroFillImage<int>(jxl::Image3<int>*) Line | Count | Source | 254 | 3 | void ZeroFillImage(Image3<T>* image) { | 255 | 12 | for (size_t c = 0; c < 3; ++c) { | 256 | 18 | for (size_t y = 0; y < image->ysize(); ++y) { | 257 | 9 | T* JXL_RESTRICT row = image->PlaneRow(c, y); | 258 | 9 | if (image->xsize() != 0) memset(row, 0, image->xsize() * sizeof(T)); | 259 | 9 | } | 260 | 9 | } | 261 | 3 | } |
void jxl::ZeroFillImage<float>(jxl::Image3<float>*) Line | Count | Source | 254 | 2.72k | void ZeroFillImage(Image3<T>* image) { | 255 | 10.8k | for (size_t c = 0; c < 3; ++c) { | 256 | 1.63M | for (size_t y = 0; y < image->ysize(); ++y) { | 257 | 1.63M | T* JXL_RESTRICT row = image->PlaneRow(c, y); | 258 | 1.63M | if (image->xsize() != 0) memset(row, 0, image->xsize() * sizeof(T)); | 259 | 1.63M | } | 260 | 8.16k | } | 261 | 2.72k | } |
void jxl::ZeroFillImage<short>(jxl::Image3<short>*) Line | Count | Source | 254 | 10 | void ZeroFillImage(Image3<T>* image) { | 255 | 40 | for (size_t c = 0; c < 3; ++c) { | 256 | 60 | for (size_t y = 0; y < image->ysize(); ++y) { | 257 | 30 | T* JXL_RESTRICT row = image->PlaneRow(c, y); | 258 | 30 | if (image->xsize() != 0) memset(row, 0, image->xsize() * sizeof(T)); | 259 | 30 | } | 260 | 30 | } | 261 | 10 | } |
|
262 | | |
263 | | // Same as above, but operates in-place. Assumes that the `in` image was |
264 | | // allocated large enough. |
265 | | Status PadImageToBlockMultipleInPlace(Image3F* JXL_RESTRICT in, |
266 | | size_t block_dim = kBlockDim); |
267 | | |
268 | | // Downsamples an image by a given factor. |
269 | | StatusOr<Image3F> DownsampleImage(const Image3F& opsin, size_t factor); |
270 | | StatusOr<ImageF> DownsampleImage(const ImageF& image, size_t factor); |
271 | | |
272 | | } // namespace jxl |
273 | | |
274 | | #endif // LIB_JXL_IMAGE_OPS_H_ |