// Copyright (C) 2024 Davis E. King (davis@dlib.net), AdriĆ Arrufat // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_SAVE_JXL_Hh_ #define DLIB_SAVE_JXL_Hh_ #include "save_jxl_abstract.h" #include "../enable_if.h" #include "image_saver.h" #include "../matrix.h" #include "../array2d.h" #include "../pixel.h" #include "../image_processing/generic_image.h" #include <string> namespace dlib { // ---------------------------------------------------------------------------------------- namespace impl { void impl_save_jxl ( const std::string& filename, const uint8_t* data, const uint32_t width, const uint32_t height, const uint32_t num_channels, const float quality ); } // ---------------------------------------------------------------------------------------- template < typename image_type > typename disable_if<is_matrix<image_type>>::type save_jxl ( const image_type& img_, const std::string& filename, const float quality = 90 ) { #ifndef DLIB_JXL_SUPPORT /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! You are getting this error because you are trying to use the save_jxl function but you haven't defined DLIB_JXL_SUPPORT. You must do so to use this object. You must also make sure you set your build environment to link against the libjxl library. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ static_assert(sizeof(image_type) == 0, "JPEG XL support not enabled."); #endif const_image_view<image_type> img(img_); using pixel_type = typename image_traits<image_type>::pixel_type; // make sure requires clause is not broken DLIB_CASSERT(img.size() != 0, "\t save_jxl()" << "\n\t You can't save an empty image as a JPEG XL." ); DLIB_CASSERT(0 <= quality && quality <= 100, "\t save_jxl()" << "\n\t Invalid quality value." << "\n\t quality: " << quality ); auto data = reinterpret_cast<const uint8_t*>(image_data(img)); const int width = img.nc(); const int height = img.nr(); const int depth = pixel_traits<pixel_type>::num; // Fast path: rgb, rgb_alpha, 8-bit grayscale if (pixel_traits<pixel_type>::rgb || pixel_traits<pixel_type>::rgb_alpha || (pixel_traits<pixel_type>::grayscale && std::is_same<typename pixel_traits<pixel_type>::basic_pixel_type, unsigned char>())) { impl::impl_save_jxl(filename, data, width, height, depth, quality); } else { // This is probably a single-channel float image resulting from some matrix operation. if (depth == 1) { array2d<unsigned char> temp; assign_image(temp, img); auto data = reinterpret_cast<const uint8_t*>(image_data(temp)); impl::impl_save_jxl(filename, data, width, height, 1, quality); } // This is some other kind of color image so just save it as an RGB image. else if (pixel_traits<pixel_type>::has_alpha) { array2d<rgb_alpha_pixel> temp; assign_image(temp, img); auto data = reinterpret_cast<const uint8_t*>(image_data(temp)); impl::impl_save_jxl(filename, data, width, height, 4, quality); } else { array2d<rgb_pixel> temp; assign_image(temp, img); auto data = reinterpret_cast<const uint8_t*>(image_data(temp)); impl::impl_save_jxl(filename, data, width, height, 3, quality); } } } // ---------------------------------------------------------------------------------------- template < typename EXP > void save_jxl( const matrix_exp<EXP>& img, const std::string& filename, const float quality = 90 ) { array2d<typename EXP::type> temp; assign_image(temp, img); save_jxl(temp, filename, quality); } // ---------------------------------------------------------------------------------------- } #endif // DLIB_SAVE_JXL_Hh_