// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.
// Returns linear combination of two grayscale images. template <typename T>
StatusOr<Plane<T>> LinComb(const T lambda1, const Plane<T>& image1, const T lambda2, const Plane<T>& image2) { const size_t xsize = image1.xsize(); const size_t ysize = image1.ysize();
JXL_ENSURE(xsize == image2.xsize());
JXL_ENSURE(ysize == image2.ysize());
JxlMemoryManager* memory_manager = image1.memory_manager();
JXL_ASSIGN_OR_RETURN(Plane<T> out,
Plane<T>::Create(memory_manager, xsize, ysize)); for (size_t y = 0; y < ysize; ++y) { const T* const JXL_RESTRICT row1 = image1.Row(y); const T* const JXL_RESTRICT row2 = image2.Row(y);
T* const JXL_RESTRICT row_out = out.Row(y); for (size_t x = 0; x < xsize; ++x) {
row_out[x] = lambda1 * row1[x] + lambda2 * row2[x];
}
} return out;
}
// Multiplies image by lambda in-place template <typename T> void ScaleImage(const T lambda, Plane<T>* image) { for (size_t y = 0; y < image->ysize(); ++y) {
T* const JXL_RESTRICT row = image->Row(y); for (size_t x = 0; x < image->xsize(); ++x) {
row[x] = lambda * row[x];
}
}
}
// Multiplies image by lambda in-place template <typename T> void ScaleImage(const T lambda, Image3<T>* image) { for (size_t c = 0; c < 3; ++c) {
ScaleImage(lambda, &image->Plane(c));
}
}
template <typename T> void FillImage(const T value, Plane<T>* image) { for (size_t y = 0; y < image->ysize(); ++y) {
T* const JXL_RESTRICT row = image->Row(y); for (size_t x = 0; x < image->xsize(); ++x) {
row[x] = value;
}
}
}
template <typename T> void ZeroFillImage(Plane<T>* image) { if (image->xsize() == 0) return; for (size_t y = 0; y < image->ysize(); ++y) {
T* const JXL_RESTRICT row = image->Row(y);
memset(row, 0, image->xsize() * sizeof(T));
}
}
// Mirrors out of bounds coordinates and returns valid coordinates unchanged. // We assume the radius (distance outside the image) is small compared to the // image size, otherwise this might not terminate. // The mirror is outside the last column (border pixel is also replicated). staticinline int64_t Mirror(int64_t x, const int64_t xsize) {
JXL_DASSERT(xsize != 0);
// TODO(janwas): replace with branchless version while (x < 0 || x >= xsize) { if (x < 0) {
x = -x - 1;
} else {
x = 2 * xsize - 1 - x;
}
} return x;
}
// Wrap modes for ensuring X/Y coordinates are in the valid range [0, size):
// Returns the same coordinate: required for TFNode with Border(), or useful // when we know "coord" is already valid (e.g. interior of an image). struct WrapUnchanged {
JXL_INLINE int64_t operator()(const int64_t coord, int64_t /*size*/) const { return coord;
}
};
// Similar to Wrap* but for row pointers (reduces Row() multiplications).
// Computes the minimum and maximum pixel value. template <typename T> void ImageMinMax(const Plane<T>& image, T* const JXL_RESTRICT min,
T* const JXL_RESTRICT max) {
*min = std::numeric_limits<T>::max();
*max = std::numeric_limits<T>::lowest(); for (size_t y = 0; y < image.ysize(); ++y) { const T* const JXL_RESTRICT row = image.Row(y); for (size_t x = 0; x < image.xsize(); ++x) {
*min = std::min(*min, row[x]);
*max = std::max(*max, row[x]);
}
}
}
// Initializes all planes to the same "value". template <typename T> void FillImage(const T value, Image3<T>* image) { for (size_t c = 0; c < 3; ++c) { for (size_t y = 0; y < image->ysize(); ++y) {
T* JXL_RESTRICT row = image->PlaneRow(c, y); for (size_t x = 0; x < image->xsize(); ++x) {
row[x] = value;
}
}
}
}
template <typename T> void FillPlane(const T value, Plane<T>* image, Rect rect) { for (size_t y = 0; y < rect.ysize(); ++y) {
T* JXL_RESTRICT row = rect.Row(image, y); for (size_t x = 0; x < rect.xsize(); ++x) {
row[x] = value;
}
}
}
template <typename T> void ZeroFillImage(Image3<T>* image) { for (size_t c = 0; c < 3; ++c) { for (size_t y = 0; y < image->ysize(); ++y) {
T* JXL_RESTRICT row = image->PlaneRow(c, y); if (image->xsize() != 0) memset(row, 0, image->xsize() * sizeof(T));
}
}
}
// Same as above, but operates in-place. Assumes that the `in` image was // allocated large enough.
Status PadImageToBlockMultipleInPlace(Image3F* JXL_RESTRICT in,
size_t block_dim = kBlockDim);
// Downsamples an image by a given factor.
StatusOr<Image3F> DownsampleImage(const Image3F& opsin, size_t factor);
StatusOr<ImageF> DownsampleImage(const ImageF& image, size_t factor);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.