/src/libjxl/lib/jxl/image_ops.cc
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 | | #include "lib/jxl/image_ops.h" |
7 | | |
8 | | #include <jxl/memory_manager.h> |
9 | | |
10 | | #include <cstddef> |
11 | | #include <cstring> |
12 | | |
13 | | #include "lib/jxl/base/common.h" |
14 | | #include "lib/jxl/base/compiler_specific.h" |
15 | | #include "lib/jxl/base/status.h" |
16 | | #include "lib/jxl/frame_dimensions.h" |
17 | | #include "lib/jxl/image.h" |
18 | | |
19 | | namespace jxl { |
20 | | |
21 | | Status PadImageToBlockMultipleInPlace(Image3F* JXL_RESTRICT in, |
22 | 283 | size_t block_dim) { |
23 | 283 | const size_t xsize_orig = in->xsize(); |
24 | 283 | const size_t ysize_orig = in->ysize(); |
25 | 283 | const size_t xsize = RoundUpTo(xsize_orig, block_dim); |
26 | 283 | const size_t ysize = RoundUpTo(ysize_orig, block_dim); |
27 | | // Expands image size to the originally-allocated size. |
28 | 283 | JXL_RETURN_IF_ERROR(in->ShrinkTo(xsize, ysize)); |
29 | 1.13k | for (size_t c = 0; c < 3; c++) { |
30 | 194k | for (size_t y = 0; y < ysize_orig; y++) { |
31 | 193k | float* JXL_RESTRICT row = in->PlaneRow(c, y); |
32 | 833k | for (size_t x = xsize_orig; x < xsize; x++) { |
33 | 639k | row[x] = row[xsize_orig - 1]; |
34 | 639k | } |
35 | 193k | } |
36 | 849 | const float* JXL_RESTRICT row_src = in->ConstPlaneRow(c, ysize_orig - 1); |
37 | 3.02k | for (size_t y = ysize_orig; y < ysize; y++) { |
38 | 2.17k | memcpy(in->PlaneRow(c, y), row_src, xsize * sizeof(float)); |
39 | 2.17k | } |
40 | 849 | } |
41 | 283 | return true; |
42 | 283 | } |
43 | | |
44 | | static Status DoDownsampleImage(const ImageF& input, size_t factor, |
45 | 0 | ImageF* output) { |
46 | 0 | JXL_ENSURE(factor != 1); |
47 | 0 | JXL_RETURN_IF_ERROR(output->ShrinkTo(DivCeil(input.xsize(), factor), |
48 | 0 | DivCeil(input.ysize(), factor))); |
49 | 0 | size_t in_stride = input.PixelsPerRow(); |
50 | 0 | for (size_t y = 0; y < output->ysize(); y++) { |
51 | 0 | float* row_out = output->Row(y); |
52 | 0 | const float* row_in = input.Row(factor * y); |
53 | 0 | for (size_t x = 0; x < output->xsize(); x++) { |
54 | 0 | size_t cnt = 0; |
55 | 0 | float sum = 0; |
56 | 0 | for (size_t iy = 0; iy < factor && iy + factor * y < input.ysize(); |
57 | 0 | iy++) { |
58 | 0 | for (size_t ix = 0; ix < factor && ix + factor * x < input.xsize(); |
59 | 0 | ix++) { |
60 | 0 | sum += row_in[iy * in_stride + x * factor + ix]; |
61 | 0 | cnt++; |
62 | 0 | } |
63 | 0 | } |
64 | 0 | row_out[x] = sum / cnt; |
65 | 0 | } |
66 | 0 | } |
67 | 0 | return true; |
68 | 0 | } |
69 | | |
70 | 0 | StatusOr<ImageF> DownsampleImage(const ImageF& image, size_t factor) { |
71 | 0 | ImageF downsampled; |
72 | | // Allocate extra space to avoid a reallocation when padding. |
73 | 0 | JxlMemoryManager* memory_manager = image.memory_manager(); |
74 | 0 | JXL_ASSIGN_OR_RETURN( |
75 | 0 | downsampled, |
76 | 0 | ImageF::Create(memory_manager, DivCeil(image.xsize(), factor) + kBlockDim, |
77 | 0 | DivCeil(image.ysize(), factor) + kBlockDim)); |
78 | 0 | JXL_RETURN_IF_ERROR(DoDownsampleImage(image, factor, &downsampled)); |
79 | 0 | return downsampled; |
80 | 0 | } |
81 | | |
82 | 0 | StatusOr<Image3F> DownsampleImage(const Image3F& opsin, size_t factor) { |
83 | 0 | JXL_ENSURE(factor != 1); |
84 | | // Allocate extra space to avoid a reallocation when padding. |
85 | 0 | Image3F downsampled; |
86 | 0 | JxlMemoryManager* memory_manager = opsin.memory_manager(); |
87 | 0 | JXL_ASSIGN_OR_RETURN( |
88 | 0 | downsampled, Image3F::Create(memory_manager, |
89 | 0 | DivCeil(opsin.xsize(), factor) + kBlockDim, |
90 | 0 | DivCeil(opsin.ysize(), factor) + kBlockDim)); |
91 | 0 | JXL_RETURN_IF_ERROR(downsampled.ShrinkTo(downsampled.xsize() - kBlockDim, |
92 | 0 | downsampled.ysize() - kBlockDim)); |
93 | 0 | for (size_t c = 0; c < 3; c++) { |
94 | 0 | JXL_RETURN_IF_ERROR( |
95 | 0 | DoDownsampleImage(opsin.Plane(c), factor, &downsampled.Plane(c))); |
96 | 0 | } |
97 | 0 | return downsampled; |
98 | 0 | } |
99 | | |
100 | | } // namespace jxl |