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