Coverage Report

Created: 2025-06-16 07:00

/src/libjxl/lib/jxl/enc_debug_image.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/enc_debug_image.h"
7
8
#include <jxl/color_encoding.h>
9
#include <jxl/memory_manager.h>
10
#include <jxl/types.h>
11
12
#include <cstddef>
13
#include <cstdint>
14
#include <limits>
15
#include <type_traits>
16
#include <vector>
17
18
#include "lib/jxl/base/common.h"
19
#include "lib/jxl/base/compiler_specific.h"
20
#include "lib/jxl/base/rect.h"
21
#include "lib/jxl/base/status.h"
22
#include "lib/jxl/color_encoding_internal.h"
23
#include "lib/jxl/dec_cache.h"
24
#include "lib/jxl/dec_external_image.h"
25
#include "lib/jxl/dec_xyb.h"
26
#include "lib/jxl/enc_params.h"
27
#include "lib/jxl/image.h"
28
#include "lib/jxl/image_metadata.h"
29
#include "lib/jxl/image_ops.h"
30
31
namespace jxl {
32
33
namespace {
34
template <typename From>
35
0
StatusOr<Image3F> ConvertToFloat(const Image3<From>& from) {
36
0
  float factor = 1.0f / std::numeric_limits<From>::max();
37
0
  if (std::is_same<From, double>::value || std::is_same<From, float>::value) {
38
0
    factor = 1.0f;
39
0
  }
40
0
  JxlMemoryManager* memory_manager = from.memory_manager();
41
0
  JXL_ASSIGN_OR_RETURN(
42
0
      Image3F to, Image3F::Create(memory_manager, from.xsize(), from.ysize()));
43
0
  for (size_t c = 0; c < 3; ++c) {
44
0
    for (size_t y = 0; y < from.ysize(); ++y) {
45
0
      const From* const JXL_RESTRICT row_from = from.ConstPlaneRow(c, y);
46
0
      float* const JXL_RESTRICT row_to = to.PlaneRow(c, y);
47
0
      for (size_t x = 0; x < from.xsize(); ++x) {
48
0
        row_to[x] = row_from[x] * factor;
49
0
      }
50
0
    }
51
0
  }
52
0
  return to;
53
0
}
Unexecuted instantiation: enc_debug_image.cc:jxl::StatusOr<jxl::Image3<float> > jxl::(anonymous namespace)::ConvertToFloat<float>(jxl::Image3<float> const&)
Unexecuted instantiation: enc_debug_image.cc:jxl::StatusOr<jxl::Image3<float> > jxl::(anonymous namespace)::ConvertToFloat<unsigned char>(jxl::Image3<unsigned char> const&)
54
55
template <typename T>
56
Status DumpImageT(const CompressParams& cparams, const char* label,
57
0
                  const ColorEncoding& color_encoding, const Image3<T>& image) {
58
0
  if (!cparams.debug_image) return true;
59
0
  JXL_ASSIGN_OR_RETURN(Image3F float_image, ConvertToFloat(image));
60
0
  JxlColorEncoding color = color_encoding.ToExternal();
61
0
  size_t num_pixels = 3 * image.xsize() * image.ysize();
62
0
  std::vector<uint16_t> pixels(num_pixels);
63
0
  const ImageF* channels[3];
64
0
  for (int c = 0; c < 3; ++c) {
65
0
    channels[c] = &float_image.Plane(c);
66
0
  }
67
0
  JXL_RETURN_IF_ERROR(ConvertChannelsToExternal(
68
0
      channels, 3, 16, false, JXL_BIG_ENDIAN, 6 * image.xsize(), nullptr,
69
0
      pixels.data(), 2 * num_pixels, PixelCallback(), Orientation::kIdentity));
70
0
  (*cparams.debug_image)(cparams.debug_image_opaque, label, image.xsize(),
71
0
                         image.ysize(), &color, pixels.data());
72
0
  return true;
73
0
}
Unexecuted instantiation: enc_debug_image.cc:jxl::Status jxl::(anonymous namespace)::DumpImageT<float>(jxl::CompressParams const&, char const*, jxl::ColorEncoding const&, jxl::Image3<float> const&)
Unexecuted instantiation: enc_debug_image.cc:jxl::Status jxl::(anonymous namespace)::DumpImageT<unsigned char>(jxl::CompressParams const&, char const*, jxl::ColorEncoding const&, jxl::Image3<unsigned char> const&)
74
75
template <typename T>
76
Status DumpPlaneNormalizedT(const CompressParams& cparams, const char* label,
77
0
                            const Plane<T>& image) {
78
0
  T min;
79
0
  T max;
80
0
  ImageMinMax(image, &min, &max);
81
0
  JxlMemoryManager* memory_manager = image.memory_manager();
82
83
0
  JXL_ASSIGN_OR_RETURN(
84
0
      Image3B normalized,
85
0
      Image3B::Create(memory_manager, image.xsize(), image.ysize()));
86
0
  for (size_t c = 0; c < 3; ++c) {
87
0
    float mul = min == max ? 0 : (255.0f / (max - min));
88
0
    for (size_t y = 0; y < image.ysize(); ++y) {
89
0
      const T* JXL_RESTRICT row_in = image.ConstRow(y);
90
0
      uint8_t* JXL_RESTRICT row_out = normalized.PlaneRow(c, y);
91
0
      for (size_t x = 0; x < image.xsize(); ++x) {
92
0
        row_out[x] = static_cast<uint8_t>((row_in[x] - min) * mul);
93
0
      }
94
0
    }
95
0
  }
96
0
  return DumpImageT(cparams, label, ColorEncoding::SRGB(), normalized);
97
0
}
Unexecuted instantiation: enc_debug_image.cc:jxl::Status jxl::(anonymous namespace)::DumpPlaneNormalizedT<float>(jxl::CompressParams const&, char const*, jxl::Plane<float> const&)
Unexecuted instantiation: enc_debug_image.cc:jxl::Status jxl::(anonymous namespace)::DumpPlaneNormalizedT<unsigned char>(jxl::CompressParams const&, char const*, jxl::Plane<unsigned char> const&)
98
99
}  // namespace
100
101
Status DumpImage(const CompressParams& cparams, const char* label,
102
0
                 const Image3<float>& image) {
103
0
  return DumpImageT(cparams, label, ColorEncoding::SRGB(), image);
104
0
}
105
106
Status DumpImage(const CompressParams& cparams, const char* label,
107
0
                 const Image3<uint8_t>& image) {
108
0
  return DumpImageT(cparams, label, ColorEncoding::SRGB(), image);
109
0
}
110
111
Status DumpXybImage(const CompressParams& cparams, const char* label,
112
0
                    const Image3F& image) {
113
0
  if (!cparams.debug_image) return true;
114
0
  JxlMemoryManager* memory_manager = image.memory_manager();
115
116
0
  JXL_ASSIGN_OR_RETURN(
117
0
      Image3F linear,
118
0
      Image3F::Create(memory_manager, image.xsize(), image.ysize()));
119
0
  OpsinParams opsin_params;
120
0
  opsin_params.Init(kDefaultIntensityTarget);
121
0
  JXL_RETURN_IF_ERROR(
122
0
      OpsinToLinear(image, Rect(linear), nullptr, &linear, opsin_params));
123
124
0
  return DumpImageT(cparams, label, ColorEncoding::LinearSRGB(), linear);
125
0
}
126
127
Status DumpPlaneNormalized(const CompressParams& cparams, const char* label,
128
0
                           const Plane<float>& image) {
129
0
  return DumpPlaneNormalizedT(cparams, label, image);
130
0
}
131
132
Status DumpPlaneNormalized(const CompressParams& cparams, const char* label,
133
0
                           const Plane<uint8_t>& image) {
134
0
  return DumpPlaneNormalizedT(cparams, label, image);
135
0
}
136
137
}  // namespace jxl