/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 |