transform.cc (3540B)
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/modular/transform/transform.h" 7 8 #include <cinttypes> 9 10 #include "lib/jxl/base/printf_macros.h" 11 #include "lib/jxl/fields.h" 12 #include "lib/jxl/modular/modular_image.h" 13 #include "lib/jxl/modular/transform/palette.h" 14 #include "lib/jxl/modular/transform/rct.h" 15 #include "lib/jxl/modular/transform/squeeze.h" 16 17 namespace jxl { 18 19 SqueezeParams::SqueezeParams() { Bundle::Init(this); } 20 Transform::Transform(TransformId id) { 21 Bundle::Init(this); 22 this->id = id; 23 } 24 25 Status Transform::Inverse(Image &input, const weighted::Header &wp_header, 26 ThreadPool *pool) { 27 JXL_DEBUG_V(6, "Input channels (%" PRIuS ", %" PRIuS " meta): ", 28 input.channel.size(), input.nb_meta_channels); 29 switch (id) { 30 case TransformId::kRCT: 31 return InvRCT(input, begin_c, rct_type, pool); 32 case TransformId::kSqueeze: 33 return InvSqueeze(input, squeezes, pool); 34 case TransformId::kPalette: 35 return InvPalette(input, begin_c, nb_colors, nb_deltas, predictor, 36 wp_header, pool); 37 default: 38 return JXL_FAILURE("Unknown transformation (ID=%u)", 39 static_cast<unsigned int>(id)); 40 } 41 } 42 43 Status Transform::MetaApply(Image &input) { 44 JXL_DEBUG_V(6, "MetaApply input: %s", input.DebugString().c_str()); 45 switch (id) { 46 case TransformId::kRCT: 47 JXL_DEBUG_V(2, "Transform: kRCT, rct_type=%" PRIu32, rct_type); 48 return CheckEqualChannels(input, begin_c, begin_c + 2); 49 case TransformId::kSqueeze: 50 JXL_DEBUG_V(2, "Transform: kSqueeze:"); 51 #if JXL_DEBUG_V_LEVEL >= 2 52 { 53 auto squeezes_copy = squeezes; 54 if (squeezes_copy.empty()) { 55 DefaultSqueezeParameters(&squeezes_copy, input); 56 } 57 for (const auto ¶ms : squeezes_copy) { 58 JXL_DEBUG_V( 59 2, 60 " squeeze params: horizontal=%d, in_place=%d, begin_c=%" PRIu32 61 ", num_c=%" PRIu32, 62 params.horizontal, params.in_place, params.begin_c, params.num_c); 63 } 64 } 65 #endif 66 return MetaSqueeze(input, &squeezes); 67 case TransformId::kPalette: 68 JXL_DEBUG_V(2, 69 "Transform: kPalette, begin_c=%" PRIu32 ", num_c=%" PRIu32 70 ", nb_colors=%" PRIu32 ", nb_deltas=%" PRIu32, 71 begin_c, num_c, nb_colors, nb_deltas); 72 return MetaPalette(input, begin_c, begin_c + num_c - 1, nb_colors, 73 nb_deltas, lossy_palette); 74 default: 75 return JXL_FAILURE("Unknown transformation (ID=%u)", 76 static_cast<unsigned int>(id)); 77 } 78 } 79 80 Status CheckEqualChannels(const Image &image, uint32_t c1, uint32_t c2) { 81 if (c1 > image.channel.size() || c2 >= image.channel.size() || c2 < c1) { 82 return JXL_FAILURE("Invalid channel range: %u..%u (there are only %" PRIuS 83 " channels)", 84 c1, c2, image.channel.size()); 85 } 86 if (c1 < image.nb_meta_channels && c2 >= image.nb_meta_channels) { 87 return JXL_FAILURE("Invalid: transforming mix of meta and nonmeta"); 88 } 89 const auto &ch1 = image.channel[c1]; 90 for (size_t c = c1 + 1; c <= c2; c++) { 91 const auto &ch2 = image.channel[c]; 92 if (ch1.w != ch2.w || ch1.h != ch2.h || ch1.hshift != ch2.hshift || 93 ch1.vshift != ch2.vshift) { 94 return false; 95 } 96 } 97 return true; 98 } 99 100 } // namespace jxl