dec_cache.h (7359B)
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 #ifndef LIB_JXL_DEC_CACHE_H_ 7 #define LIB_JXL_DEC_CACHE_H_ 8 9 #include <jxl/decode.h> 10 #include <jxl/memory_manager.h> 11 #include <jxl/types.h> 12 13 #include <atomic> 14 #include <cmath> 15 #include <cstdint> 16 #include <hwy/base.h> // HWY_ALIGN_MAX 17 #include <memory> 18 #include <vector> 19 20 #include "lib/jxl/base/common.h" // kMaxNumPasses 21 #include "lib/jxl/base/compiler_specific.h" 22 #include "lib/jxl/base/data_parallel.h" 23 #include "lib/jxl/base/status.h" 24 #include "lib/jxl/common.h" 25 #include "lib/jxl/dct_util.h" 26 #include "lib/jxl/dec_ans.h" 27 #include "lib/jxl/dec_xyb.h" 28 #include "lib/jxl/frame_dimensions.h" 29 #include "lib/jxl/frame_header.h" 30 #include "lib/jxl/image.h" 31 #include "lib/jxl/image_bundle.h" 32 #include "lib/jxl/image_metadata.h" 33 #include "lib/jxl/memory_manager_internal.h" 34 #include "lib/jxl/passes_state.h" 35 #include "lib/jxl/render_pipeline/render_pipeline.h" 36 #include "lib/jxl/render_pipeline/render_pipeline_stage.h" 37 #include "lib/jxl/render_pipeline/stage_upsampling.h" 38 39 namespace jxl { 40 41 constexpr size_t kSigmaBorder = 1; 42 constexpr size_t kSigmaPadding = 2; 43 44 struct PixelCallback { 45 PixelCallback() = default; 46 PixelCallback(JxlImageOutInitCallback init, JxlImageOutRunCallback run, 47 JxlImageOutDestroyCallback destroy, void* init_opaque) 48 : init(init), run(run), destroy(destroy), init_opaque(init_opaque) { 49 #if (JXL_IS_DEBUG_BUILD) 50 const bool has_init = (init != nullptr); 51 const bool has_run = (run != nullptr); 52 const bool has_destroy = (destroy != nullptr); 53 const bool healthy = (has_init == has_run) && (has_run == has_destroy); 54 JXL_DASSERT(healthy); 55 #endif 56 } 57 58 bool IsPresent() const { return run != nullptr; } 59 60 void* Init(size_t num_threads, size_t num_pixels) const { 61 return init(init_opaque, num_threads, num_pixels); 62 } 63 64 JxlImageOutInitCallback init = nullptr; 65 JxlImageOutRunCallback run = nullptr; 66 JxlImageOutDestroyCallback destroy = nullptr; 67 void* init_opaque = nullptr; 68 }; 69 70 struct ImageOutput { 71 // Pixel format of the output pixels, used for buffer and callback output. 72 JxlPixelFormat format; 73 // Output bit depth for unsigned data types, used for float to int conversion. 74 size_t bits_per_sample; 75 // Callback for line-by-line output. 76 PixelCallback callback; 77 // Pixel buffer for image output. 78 void* buffer; 79 size_t buffer_size; 80 // Length of a row of image_buffer in bytes (based on oriented width). 81 size_t stride; 82 }; 83 84 // Per-frame decoder state. All the images here should be accessed through a 85 // group rect (either with block units or pixel units). 86 struct PassesDecoderState { 87 explicit PassesDecoderState(JxlMemoryManager* memory_manager) 88 : shared_storage(memory_manager), 89 frame_storage_for_referencing(memory_manager) {} 90 91 PassesSharedState shared_storage; 92 // Allows avoiding copies for encoder loop. 93 const PassesSharedState* JXL_RESTRICT shared = &shared_storage; 94 95 // 8x upsampling stage for DC. 96 std::unique_ptr<RenderPipelineStage> upsampler8x; 97 98 // For ANS decoding. 99 std::vector<ANSCode> code; 100 std::vector<std::vector<uint8_t>> context_map; 101 102 // Multiplier to be applied to the quant matrices of the x channel. 103 float x_dm_multiplier; 104 float b_dm_multiplier; 105 106 // Sigma values for EPF. 107 ImageF sigma; 108 109 // Image dimensions before applying undo_orientation. 110 size_t width; 111 size_t height; 112 ImageOutput main_output; 113 std::vector<ImageOutput> extra_output; 114 115 // Whether to use int16 float-XYB-to-uint8-srgb conversion. 116 bool fast_xyb_srgb8_conversion; 117 118 // If true, the RGBA output will be unpremultiplied before writing to the 119 // output. 120 bool unpremul_alpha; 121 122 // The render pipeline will apply this orientation to bring the image to the 123 // intended display orientation. 124 Orientation undo_orientation; 125 126 // Used for seeding noise. 127 size_t visible_frame_index = 0; 128 size_t nonvisible_frame_index = 0; 129 130 // Keep track of the transform types used. 131 std::atomic<uint32_t> used_acs{0}; 132 133 // Storage for coefficients if in "accumulate" mode. 134 std::unique_ptr<ACImage> coefficients = make_unique<ACImageT<int32_t>>(); 135 136 // Rendering pipeline. 137 std::unique_ptr<RenderPipeline> render_pipeline; 138 139 // Storage for the current frame if it can be referenced by future frames. 140 ImageBundle frame_storage_for_referencing; 141 142 struct PipelineOptions { 143 bool use_slow_render_pipeline; 144 bool coalescing; 145 bool render_spotcolors; 146 bool render_noise; 147 }; 148 149 JxlMemoryManager* memory_manager() const { return shared->memory_manager; } 150 151 Status PreparePipeline(const FrameHeader& frame_header, 152 const ImageMetadata* metadata, ImageBundle* decoded, 153 PipelineOptions options); 154 155 // Information for colour conversions. 156 OutputEncodingInfo output_encoding_info; 157 158 // Initializes decoder-specific structures using information from *shared. 159 Status Init(const FrameHeader& frame_header) { 160 JxlMemoryManager* memory_manager = this->memory_manager(); 161 x_dm_multiplier = std::pow(1 / (1.25f), frame_header.x_qm_scale - 2.0f); 162 b_dm_multiplier = std::pow(1 / (1.25f), frame_header.b_qm_scale - 2.0f); 163 164 main_output.callback = PixelCallback(); 165 main_output.buffer = nullptr; 166 extra_output.clear(); 167 168 fast_xyb_srgb8_conversion = false; 169 unpremul_alpha = false; 170 undo_orientation = Orientation::kIdentity; 171 172 used_acs = 0; 173 174 upsampler8x = GetUpsamplingStage(shared->metadata->transform_data, 0, 3); 175 if (frame_header.loop_filter.epf_iters > 0) { 176 JXL_ASSIGN_OR_RETURN( 177 sigma, 178 ImageF::Create(memory_manager, 179 shared->frame_dim.xsize_blocks + 2 * kSigmaPadding, 180 shared->frame_dim.ysize_blocks + 2 * kSigmaPadding)); 181 } 182 return true; 183 } 184 185 // Initialize the decoder state after all of DC is decoded. 186 Status InitForAC(size_t num_passes, ThreadPool* pool); 187 }; 188 189 // Temp images required for decoding a single group. Reduces memory allocations 190 // for large images because we only initialize min(#threads, #groups) instances. 191 struct HWY_ALIGN_MAX GroupDecCache { 192 Status InitOnce(JxlMemoryManager* memory_manager, size_t num_passes, 193 size_t used_acs); 194 195 Status InitDCBufferOnce(JxlMemoryManager* memory_manager) { 196 if (dc_buffer.xsize() == 0) { 197 JXL_ASSIGN_OR_RETURN( 198 dc_buffer, 199 ImageF::Create(memory_manager, 200 kGroupDimInBlocks + kRenderPipelineXOffset * 2, 201 kGroupDimInBlocks + 4)); 202 } 203 return true; 204 } 205 206 // Scratch space used by DecGroupImpl(). 207 float* dec_group_block; 208 int32_t* dec_group_qblock; 209 int16_t* dec_group_qblock16; 210 211 // For TransformToPixels. 212 float* scratch_space; 213 // Note that scratch_space is never used at the same time as dec_group_qblock. 214 // Moreover, only one of dec_group_qblock16 is ever used. 215 // TODO(veluca): figure out if we can save allocations. 216 217 // AC decoding 218 Image3I num_nzeroes[kMaxNumPasses]; 219 220 // Buffer for DC upsampling. 221 ImageF dc_buffer; 222 223 private: 224 AlignedMemory float_memory_; 225 AlignedMemory int32_memory_; 226 AlignedMemory int16_memory_; 227 size_t max_block_area_ = 0; 228 }; 229 230 } // namespace jxl 231 232 #endif // LIB_JXL_DEC_CACHE_H_