// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. #ifndef LIB_JXL_RENDER_PIPELINE_LOW_MEMORY_RENDER_PIPELINE_H_ #define LIB_JXL_RENDER_PIPELINE_LOW_MEMORY_RENDER_PIPELINE_H_ #include #include "lib/jxl/dec_group_border.h" #include "lib/jxl/render_pipeline/render_pipeline.h" namespace jxl { // A multithreaded, low-memory rendering pipeline that only allocates a minimal // amount of buffers. class LowMemoryRenderPipeline final : public RenderPipeline { private: std::vector> PrepareBuffers( size_t group_id, size_t thread_id) override; void PrepareForThreadsInternal(size_t num, bool use_group_ids) override; void ProcessBuffers(size_t group_id, size_t thread_id) override; void ClearDone(size_t i) override { group_border_assigner_.ClearDone(i); } void Init() override; void EnsureBordersStorage(); size_t GroupInputXSize(size_t c) const; size_t GroupInputYSize(size_t c) const; void RenderRect(size_t thread_id, std::vector& input_data, Rect data_max_color_channel_rect, Rect image_max_color_channel_rect); void RenderPadding(size_t thread_id, Rect rect); void SaveBorders(size_t group_id, size_t c, const ImageF& in); void LoadBorders(size_t group_id, size_t c, const Rect& r, ImageF* out); std::pair ColorDimensionsToChannelDimensions( std::pair in, size_t c, size_t stage) const; std::pair BorderToStore(size_t c) const; bool use_group_ids_; // Storage for borders between groups. Borders of adjacent groups are stacked // together, e.g. bottom border of current group is followed by top border // of next group. std::vector borders_horizontal_; std::vector borders_vertical_; // Manages the status of borders. GroupBorderAssigner group_border_assigner_; // Size (in color-channel-pixels) of the border around each group that might // be assigned to that group. std::pair group_border_; // base_color_shift_ defines the size of groups in terms of final image // pixels. size_t base_color_shift_; // Buffer for decoded pixel data for a group, indexed by [thread][channel] or // [group][channel] depending on `use_group_ids_`. std::vector> group_data_; // Borders for storing group data. size_t group_data_x_border_; size_t group_data_y_border_; // Buffers for intermediate rows for the various stages, indexed by // [thread][channel][stage]. std::vector>> stage_data_; // Buffers for out-of-frame data, indexed by [thread]; every row is a // different channel. std::vector out_of_frame_data_; // For each stage, a non-kIgnored channel. std::vector anyc_; // Size of the image at each stage. std::vector image_rect_; // For each stage, for each channel, keep track of the kInOut stage that // produced the input to that stage (which corresponds to the buffer index // containing the data). -1 if data comes from the original input. std::vector> stage_input_for_channel_; // Number of (virtual) extra rows that must be processed at each stage // to produce sufficient output for future stages. std::vector virtual_ypadding_for_output_; // Same thing for columns, except these are real columns and not virtual ones. std::vector xpadding_for_output_; // First stage that doesn't have any kInOut channel. size_t first_trailing_stage_; // Origin and size of the frame after switching to image dimensions. FrameOrigin frame_origin_; size_t full_image_xsize_; size_t full_image_ysize_; size_t first_image_dim_stage_; }; } // namespace jxl #endif // LIB_JXL_RENDER_PIPELINE_LOW_MEMORY_RENDER_PIPELINE_H_