Coverage Report

Created: 2025-06-16 07:00

/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