Coverage Report

Created: 2024-05-21 06:41

/src/libjxl/lib/jxl/image_bundle.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_bundle.h"
7
8
#include <limits>
9
#include <utility>
10
11
#include "lib/jxl/base/byte_order.h"
12
#include "lib/jxl/base/printf_macros.h"
13
#include "lib/jxl/fields.h"
14
15
namespace jxl {
16
17
0
void ImageBundle::ShrinkTo(size_t xsize, size_t ysize) {
18
0
  if (HasColor()) color_.ShrinkTo(xsize, ysize);
19
0
  for (ImageF& ec : extra_channels_) {
20
0
    ec.ShrinkTo(xsize, ysize);
21
0
  }
22
0
}
23
24
// Called by all other SetFrom*.
25
void ImageBundle::SetFromImage(Image3F&& color,
26
26.6k
                               const ColorEncoding& c_current) {
27
26.6k
  JXL_CHECK(color.xsize() != 0 && color.ysize() != 0);
28
26.6k
  JXL_CHECK(metadata_->color_encoding.IsGray() == c_current.IsGray());
29
26.6k
  color_ = std::move(color);
30
26.6k
  c_current_ = c_current;
31
26.6k
  VerifySizes();
32
26.6k
}
33
34
0
void ImageBundle::VerifyMetadata() const {
35
0
  JXL_CHECK(!c_current_.ICC().empty());
36
0
  JXL_CHECK(metadata_->color_encoding.IsGray() == IsGray());
37
38
0
  if (metadata_->HasAlpha() && alpha().xsize() == 0) {
39
0
    JXL_UNREACHABLE("MD alpha_bits %u IB alpha %" PRIuS " x %" PRIuS "\n",
40
0
                    metadata_->GetAlphaBits(), alpha().xsize(),
41
0
                    alpha().ysize());
42
0
  }
43
0
  const uint32_t alpha_bits = metadata_->GetAlphaBits();
44
0
  JXL_CHECK(alpha_bits <= 32);
45
46
  // metadata_->num_extra_channels may temporarily differ from
47
  // extra_channels_.size(), e.g. after SetAlpha. They are synced by the next
48
  // call to VisitFields.
49
0
}
50
51
26.6k
void ImageBundle::VerifySizes() const {
52
26.6k
  const size_t xs = xsize();
53
26.6k
  const size_t ys = ysize();
54
55
26.6k
  if (HasExtraChannels()) {
56
0
    JXL_CHECK(xs != 0 && ys != 0);
57
0
    for (const ImageF& ec : extra_channels_) {
58
0
      JXL_CHECK(ec.xsize() == xs);
59
0
      JXL_CHECK(ec.ysize() == ys);
60
0
    }
61
0
  }
62
26.6k
}
63
64
0
size_t ImageBundle::DetectRealBitdepth() const {
65
0
  return metadata_->bit_depth.bits_per_sample;
66
67
  // TODO(lode): let this function return lower bit depth if possible, e.g.
68
  // return 8 bits in case the original image came from a 16-bit PNG that
69
  // was in fact representable as 8-bit PNG. Ensure that the implementation
70
  // returns 16 if e.g. two consecutive 16-bit values appeared in the original
71
  // image (such as 32768 and 32769), take into account that e.g. the values
72
  // 3-bit can represent is not a superset of the values 2-bit can represent,
73
  // and there may be slight imprecisions in the floating point image.
74
0
}
75
76
0
const ImageF& ImageBundle::black() const {
77
0
  JXL_ASSERT(HasBlack());
78
0
  const size_t ec = metadata_->Find(ExtraChannel::kBlack) -
79
0
                    metadata_->extra_channel_info.data();
80
0
  JXL_ASSERT(ec < extra_channels_.size());
81
0
  return extra_channels_[ec];
82
0
}
83
0
const ImageF& ImageBundle::alpha() const {
84
0
  JXL_ASSERT(HasAlpha());
85
0
  const size_t ec = metadata_->Find(ExtraChannel::kAlpha) -
86
0
                    metadata_->extra_channel_info.data();
87
0
  JXL_ASSERT(ec < extra_channels_.size());
88
0
  return extra_channels_[ec];
89
0
}
90
0
ImageF* ImageBundle::alpha() {
91
0
  JXL_ASSERT(HasAlpha());
92
0
  const size_t ec = metadata_->Find(ExtraChannel::kAlpha) -
93
0
                    metadata_->extra_channel_info.data();
94
0
  JXL_ASSERT(ec < extra_channels_.size());
95
0
  return &extra_channels_[ec];
96
0
}
97
98
0
void ImageBundle::SetAlpha(ImageF&& alpha) {
99
0
  const ExtraChannelInfo* eci = metadata_->Find(ExtraChannel::kAlpha);
100
  // Must call SetAlphaBits first, otherwise we don't know which channel index
101
0
  JXL_CHECK(eci != nullptr);
102
0
  JXL_CHECK(alpha.xsize() != 0 && alpha.ysize() != 0);
103
0
  if (extra_channels_.size() < metadata_->extra_channel_info.size()) {
104
    // TODO(jon): get rid of this case
105
0
    extra_channels_.insert(
106
0
        extra_channels_.begin() + (eci - metadata_->extra_channel_info.data()),
107
0
        std::move(alpha));
108
0
  } else {
109
0
    extra_channels_[eci - metadata_->extra_channel_info.data()] =
110
0
        std::move(alpha);
111
0
  }
112
  // num_extra_channels is automatically set in visitor
113
0
  VerifySizes();
114
0
}
115
116
0
void ImageBundle::SetExtraChannels(std::vector<ImageF>&& extra_channels) {
117
0
  for (const ImageF& plane : extra_channels) {
118
0
    JXL_CHECK(plane.xsize() != 0 && plane.ysize() != 0);
119
0
  }
120
0
  extra_channels_ = std::move(extra_channels);
121
0
  VerifySizes();
122
0
}
123
}  // namespace jxl