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