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