common.cc (2050B)
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/extras/common.h" 7 8 #include <jxl/codestream_header.h> 9 #include <jxl/types.h> 10 11 #include <cstddef> 12 #include <vector> 13 14 #include "lib/extras/packed_image.h" 15 #include "lib/jxl/base/printf_macros.h" 16 #include "lib/jxl/base/status.h" 17 18 namespace jxl { 19 namespace extras { 20 21 Status SelectFormat(const std::vector<JxlPixelFormat>& accepted_formats, 22 const JxlBasicInfo& basic_info, JxlPixelFormat* format) { 23 const size_t original_bit_depth = basic_info.bits_per_sample; 24 size_t current_bit_depth = 0; 25 size_t num_alpha_channels = (basic_info.alpha_bits != 0 ? 1 : 0); 26 size_t num_channels = basic_info.num_color_channels + num_alpha_channels; 27 for (;;) { 28 for (const JxlPixelFormat& candidate : accepted_formats) { 29 if (candidate.num_channels != num_channels) continue; 30 const size_t candidate_bit_depth = 31 PackedImage::BitsPerChannel(candidate.data_type); 32 if ( 33 // Candidate bit depth is less than what we have and still enough 34 (original_bit_depth <= candidate_bit_depth && 35 candidate_bit_depth < current_bit_depth) || 36 // Or larger than the too-small bit depth we currently have 37 (current_bit_depth < candidate_bit_depth && 38 current_bit_depth < original_bit_depth)) { 39 *format = candidate; 40 current_bit_depth = candidate_bit_depth; 41 } 42 } 43 if (current_bit_depth == 0) { 44 if (num_channels > basic_info.num_color_channels) { 45 // Try dropping the alpha channel. 46 --num_channels; 47 continue; 48 } 49 return JXL_FAILURE("no appropriate format found"); 50 } 51 break; 52 } 53 if (current_bit_depth < original_bit_depth) { 54 JXL_WARNING("encoding %" PRIuS "-bit original to %" PRIuS " bits", 55 original_bit_depth, current_bit_depth); 56 } 57 return true; 58 } 59 60 } // namespace extras 61 } // namespace jxl