diff options
Diffstat (limited to 'third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc')
-rw-r--r-- | third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc | 131 |
1 files changed, 77 insertions, 54 deletions
diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc index 9aefdd007d..27718e6413 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc @@ -6,10 +6,9 @@ #include "lib/jxl/render_pipeline/low_memory_render_pipeline.h" #include <algorithm> -#include <queue> -#include <tuple> #include "lib/jxl/base/arch_macros.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/image_ops.h" namespace jxl { @@ -174,7 +173,7 @@ size_t LowMemoryRenderPipeline::GroupInputYSize(size_t c) const { channel_shifts_[0][c].second; } -void LowMemoryRenderPipeline::EnsureBordersStorage() { +Status LowMemoryRenderPipeline::EnsureBordersStorage() { const auto& shifts = channel_shifts_[0]; if (borders_horizontal_.size() < shifts.size()) { borders_horizontal_.resize(shifts.size()); @@ -194,16 +193,20 @@ void LowMemoryRenderPipeline::EnsureBordersStorage() { 1 << shifts[c].second); Rect horizontal = Rect(0, 0, downsampled_xsize, bordery * num_yborders); if (!SameSize(horizontal, borders_horizontal_[c])) { - borders_horizontal_[c] = ImageF(horizontal.xsize(), horizontal.ysize()); + JXL_ASSIGN_OR_RETURN( + borders_horizontal_[c], + ImageF::Create(horizontal.xsize(), horizontal.ysize())); } Rect vertical = Rect(0, 0, borderx * num_xborders, downsampled_ysize); if (!SameSize(vertical, borders_vertical_[c])) { - borders_vertical_[c] = ImageF(vertical.xsize(), vertical.ysize()); + JXL_ASSIGN_OR_RETURN(borders_vertical_[c], + ImageF::Create(vertical.xsize(), vertical.ysize())); } } + return true; } -void LowMemoryRenderPipeline::Init() { +Status LowMemoryRenderPipeline::Init() { group_border_ = {0, 0}; base_color_shift_ = CeilLog2Nonzero(frame_dimensions_.xsize_upsampled_padded / frame_dimensions_.xsize_padded); @@ -255,7 +258,7 @@ void LowMemoryRenderPipeline::Init() { group_data_x_border_ = RoundUpTo(max_border.first, kGroupXAlign); group_data_y_border_ = max_border.second; - EnsureBordersStorage(); + JXL_RETURN_IF_ERROR(EnsureBordersStorage()); group_border_assigner_.Init(frame_dimensions_); for (first_trailing_stage_ = stages_.size(); first_trailing_stage_ > 0; @@ -282,7 +285,7 @@ void LowMemoryRenderPipeline::Init() { DivCeil(frame_dimensions_.ysize_upsampled, 1 << channel_shifts_[i][c].second)); } - stages_[i]->SetInputSizes(input_sizes); + JXL_RETURN_IF_ERROR(stages_[i]->SetInputSizes(input_sizes)); if (stages_[i]->SwitchToImageDimensions()) { // We don't allow kInOut after switching to image dimensions. JXL_ASSERT(i >= first_trailing_stage_); @@ -300,7 +303,7 @@ void LowMemoryRenderPipeline::Init() { for (size_t c = 0; c < shifts.size(); c++) { input_sizes[c] = {full_image_xsize_, full_image_ysize_}; } - stages_[i]->SetInputSizes(input_sizes); + JXL_RETURN_IF_ERROR(stages_[i]->SetInputSizes(input_sizes)); } anyc_.resize(stages_.size()); @@ -355,10 +358,11 @@ void LowMemoryRenderPipeline::Init() { } } } + return true; } -void LowMemoryRenderPipeline::PrepareForThreadsInternal(size_t num, - bool use_group_ids) { +Status LowMemoryRenderPipeline::PrepareForThreadsInternal(size_t num, + bool use_group_ids) { const auto& shifts = channel_shifts_[0]; use_group_ids_ = use_group_ids; size_t num_buffers = use_group_ids_ ? frame_dimensions_.num_groups : num; @@ -366,8 +370,10 @@ void LowMemoryRenderPipeline::PrepareForThreadsInternal(size_t num, group_data_.emplace_back(); group_data_[t].resize(shifts.size()); for (size_t c = 0; c < shifts.size(); c++) { - group_data_[t][c] = ImageF(GroupInputXSize(c) + group_data_x_border_ * 2, - GroupInputYSize(c) + group_data_y_border_ * 2); + JXL_ASSIGN_OR_RETURN( + group_data_[t][c], + ImageF::Create(GroupInputXSize(c) + group_data_x_border_ * 2, + GroupInputYSize(c) + group_data_y_border_ * 2)); } } // TODO(veluca): avoid reallocating buffers if not needed. @@ -390,7 +396,9 @@ void LowMemoryRenderPipeline::PrepareForThreadsInternal(size_t num, 2 * next_y_border + (1 << stages_[i]->settings_.shift_y); stage_buffer_ysize = 1 << CeilLog2Nonzero(stage_buffer_ysize); next_y_border = stages_[i]->settings_.border_y; - stage_data_[t][c][i] = ImageF(stage_buffer_xsize, stage_buffer_ysize); + JXL_ASSIGN_OR_RETURN( + stage_data_[t][c][i], + ImageF::Create(stage_buffer_xsize, stage_buffer_ysize)); } } } @@ -412,9 +420,11 @@ void LowMemoryRenderPipeline::PrepareForThreadsInternal(size_t num, std::max(left_padding, std::max(middle_padding, right_padding)); out_of_frame_data_.resize(num); for (size_t t = 0; t < num; t++) { - out_of_frame_data_[t] = ImageF(out_of_frame_xsize, shifts.size()); + JXL_ASSIGN_OR_RETURN(out_of_frame_data_[t], + ImageF::Create(out_of_frame_xsize, shifts.size())); } } + return true; } std::vector<std::pair<ImageF*, Rect>> LowMemoryRenderPipeline::PrepareBuffers( @@ -520,7 +530,8 @@ class Rows { .Translate(-group_data_x_border, -group_data_y_border) .ShiftLeft(base_color_shift) .CeilShiftRight(group_data_shift[c]) - .Translate(group_data_x_border - ssize_t(kRenderPipelineXOffset), + .Translate(group_data_x_border - + static_cast<ssize_t>(kRenderPipelineXOffset), group_data_y_border); rows_[0][c].base_ptr = channel_group_data_rect.Row(&input_data[c], 0); rows_[0][c].stride = input_data[c].PixelsPerRow(); @@ -533,7 +544,8 @@ class Rows { JXL_INLINE float* GetBuffer(int stage, int y, size_t c) const { JXL_DASSERT(stage >= -1); const RowInfo& info = rows_[stage + 1][c]; - return info.base_ptr + ssize_t(info.stride) * (y & info.ymod_minus_1); + return info.base_ptr + + static_cast<ssize_t>(info.stride) * (y & info.ymod_minus_1); } private: @@ -551,10 +563,10 @@ class Rows { } // namespace -void LowMemoryRenderPipeline::RenderRect(size_t thread_id, - std::vector<ImageF>& input_data, - Rect data_max_color_channel_rect, - Rect image_max_color_channel_rect) { +Status LowMemoryRenderPipeline::RenderRect(size_t thread_id, + std::vector<ImageF>& input_data, + Rect data_max_color_channel_rect, + Rect image_max_color_channel_rect) { // For each stage, the rect corresponding to the image area currently being // processed, in the coordinates of that stage (i.e. with the scaling factor // that that stage has). @@ -599,7 +611,7 @@ void LowMemoryRenderPipeline::RenderRect(size_t thread_id, // is no point in proceeding. Note: this uses the assumption that if there is // a stage with observable effects (i.e. a kInput stage), it only appears // after the stage that switches to image dimensions. - if (full_image_x1 <= full_image_x0) return; + if (full_image_x1 <= full_image_x0) return true; // Data structures to hold information about input/output rows and their // buffers. @@ -643,7 +655,7 @@ void LowMemoryRenderPipeline::RenderRect(size_t thread_id, } // If we already have rows from a previous iteration, we can just shift // the rows by 1 and insert the new one. - if (input_rows[i][c].size() == 2 * size_t(bordery) + 1) { + if (input_rows[i][c].size() == 2 * static_cast<size_t>(bordery) + 1) { for (ssize_t iy = 0; iy < 2 * bordery; iy++) { input_rows[i][c][iy] = input_rows[i][c][iy + 1]; } @@ -674,7 +686,7 @@ void LowMemoryRenderPipeline::RenderRect(size_t thread_id, virtual_ypadding_for_output_.end()); for (int vy = -num_extra_rows; - vy < int(image_area_rect.ysize()) + num_extra_rows; vy++) { + vy < static_cast<int>(image_area_rect.ysize()) + num_extra_rows; vy++) { for (size_t i = 0; i < first_trailing_stage_; i++) { int stage_vy = vy - num_extra_rows + virtual_ypadding_for_output_[i]; @@ -688,9 +700,10 @@ void LowMemoryRenderPipeline::RenderRect(size_t thread_id, int y = stage_vy >> channel_shifts_[i][anyc_[i]].second; - ssize_t image_y = ssize_t(group_rect[i].y0()) + y; + ssize_t image_y = static_cast<ssize_t>(group_rect[i].y0()) + y; // Do not produce rows in out-of-bounds areas. - if (image_y < 0 || image_y >= ssize_t(image_rect_[i].ysize())) { + if (image_y < 0 || + image_y >= static_cast<ssize_t>(image_rect_[i].ysize())) { continue; } @@ -698,9 +711,9 @@ void LowMemoryRenderPipeline::RenderRect(size_t thread_id, prepare_io_rows(y, i); // Produce output rows. - stages_[i]->ProcessRow(input_rows[i], output_rows, - xpadding_for_output_[i], group_rect[i].xsize(), - group_rect[i].x0(), image_y, thread_id); + JXL_RETURN_IF_ERROR(stages_[i]->ProcessRow( + input_rows[i], output_rows, xpadding_for_output_[i], + group_rect[i].xsize(), group_rect[i].x0(), image_y, thread_id)); } // Process trailing stages, i.e. the final set of non-kInOut stages; they @@ -719,7 +732,7 @@ void LowMemoryRenderPipeline::RenderRect(size_t thread_id, // Check that we are not outside of the bounds for the current rendering // rect. Not doing so might result in overwriting some rows that have been // written (or will be written) by other threads. - if (y < 0 || y >= ssize_t(image_area_rect.ysize())) { + if (y < 0 || y >= static_cast<ssize_t>(image_area_rect.ysize())) { continue; } @@ -728,7 +741,8 @@ void LowMemoryRenderPipeline::RenderRect(size_t thread_id, // (and may be necessary for correctness, as some stages assume coordinates // are within bounds). ssize_t full_image_y = frame_y0 + image_area_rect.y0() + y; - if (full_image_y < 0 || full_image_y >= ssize_t(full_image_ysize)) { + if (full_image_y < 0 || + full_image_y >= static_cast<ssize_t>(full_image_ysize)) { continue; } @@ -739,15 +753,16 @@ void LowMemoryRenderPipeline::RenderRect(size_t thread_id, i < first_image_dim_stage_ ? full_image_x0 - frame_x0 : full_image_x0; size_t y = i < first_image_dim_stage_ ? full_image_y - frame_y0 : full_image_y; - stages_[i]->ProcessRow(input_rows[first_trailing_stage_], output_rows, - /*xextra=*/0, full_image_x1 - full_image_x0, x0, y, - thread_id); + JXL_RETURN_IF_ERROR(stages_[i]->ProcessRow( + input_rows[first_trailing_stage_], output_rows, + /*xextra=*/0, full_image_x1 - full_image_x0, x0, y, thread_id)); } } + return true; } -void LowMemoryRenderPipeline::RenderPadding(size_t thread_id, Rect rect) { - if (rect.xsize() == 0) return; +Status LowMemoryRenderPipeline::RenderPadding(size_t thread_id, Rect rect) { + if (rect.xsize() == 0) return true; size_t numc = channel_shifts_[0].size(); RenderPipelineStage::RowInfo input_rows(numc, std::vector<float*>(1)); RenderPipelineStage::RowInfo output_rows; @@ -760,15 +775,16 @@ void LowMemoryRenderPipeline::RenderPadding(size_t thread_id, Rect rect) { stages_[first_image_dim_stage_ - 1]->ProcessPaddingRow( input_rows, rect.xsize(), rect.x0(), rect.y0() + y); for (size_t i = first_image_dim_stage_; i < stages_.size(); i++) { - stages_[i]->ProcessRow(input_rows, output_rows, - /*xextra=*/0, rect.xsize(), rect.x0(), - rect.y0() + y, thread_id); + JXL_RETURN_IF_ERROR(stages_[i]->ProcessRow( + input_rows, output_rows, + /*xextra=*/0, rect.xsize(), rect.x0(), rect.y0() + y, thread_id)); } } + return true; } -void LowMemoryRenderPipeline::ProcessBuffers(size_t group_id, - size_t thread_id) { +Status LowMemoryRenderPipeline::ProcessBuffers(size_t group_id, + size_t thread_id) { std::vector<ImageF>& input_data = group_data_[use_group_ids_ ? group_id : thread_id]; @@ -804,38 +820,43 @@ void LowMemoryRenderPipeline::ProcessBuffers(size_t group_id, if (group_id == 0 && (image_rect.xsize() == 0 || image_rect.ysize() == 0)) { // If this frame does not intersect with the full image, we have to // initialize the whole image area with RenderPadding. - RenderPadding(thread_id, - Rect(0, 0, full_image_xsize_, full_image_ysize_)); + JXL_RETURN_IF_ERROR(RenderPadding( + thread_id, Rect(0, 0, full_image_xsize_, full_image_ysize_))); } // Render padding for groups that intersect with the full image. The case // where no groups intersect was handled above. if (group_rect.xsize() > 0 && group_rect.ysize() > 0) { if (gx == 0 && gy == 0) { - RenderPadding(thread_id, Rect(0, 0, x0, y0)); + JXL_RETURN_IF_ERROR(RenderPadding(thread_id, Rect(0, 0, x0, y0))); } if (gy == 0) { - RenderPadding(thread_id, Rect(x0, 0, x1 - x0, y0)); + JXL_RETURN_IF_ERROR(RenderPadding(thread_id, Rect(x0, 0, x1 - x0, y0))); } if (gx == 0) { - RenderPadding(thread_id, Rect(0, y0, x0, y1 - y0)); + JXL_RETURN_IF_ERROR(RenderPadding(thread_id, Rect(0, y0, x0, y1 - y0))); } if (gx == 0 && gy + 1 == frame_dimensions_.ysize_groups) { - RenderPadding(thread_id, Rect(0, y1, x0, full_image_ysize_ - y1)); + JXL_RETURN_IF_ERROR( + RenderPadding(thread_id, Rect(0, y1, x0, full_image_ysize_ - y1))); } if (gy + 1 == frame_dimensions_.ysize_groups) { - RenderPadding(thread_id, Rect(x0, y1, x1 - x0, full_image_ysize_ - y1)); + JXL_RETURN_IF_ERROR(RenderPadding( + thread_id, Rect(x0, y1, x1 - x0, full_image_ysize_ - y1))); } if (gy == 0 && gx + 1 == frame_dimensions_.xsize_groups) { - RenderPadding(thread_id, Rect(x1, 0, full_image_xsize_ - x1, y0)); + JXL_RETURN_IF_ERROR( + RenderPadding(thread_id, Rect(x1, 0, full_image_xsize_ - x1, y0))); } if (gx + 1 == frame_dimensions_.xsize_groups) { - RenderPadding(thread_id, Rect(x1, y0, full_image_xsize_ - x1, y1 - y0)); + JXL_RETURN_IF_ERROR(RenderPadding( + thread_id, Rect(x1, y0, full_image_xsize_ - x1, y1 - y0))); } if (gy + 1 == frame_dimensions_.ysize_groups && gx + 1 == frame_dimensions_.xsize_groups) { - RenderPadding(thread_id, Rect(x1, y1, full_image_xsize_ - x1, - full_image_ysize_ - y1)); + JXL_RETURN_IF_ERROR(RenderPadding( + thread_id, + Rect(x1, y1, full_image_xsize_ - x1, full_image_ysize_ - y1))); } } } @@ -857,8 +878,10 @@ void LowMemoryRenderPipeline::ProcessBuffers(size_t group_id, gy * frame_dimensions_.group_dim, image_max_color_channel_rect.xsize(), image_max_color_channel_rect.ysize()); - RenderRect(thread_id, input_data, data_max_color_channel_rect, - image_max_color_channel_rect); + JXL_RETURN_IF_ERROR(RenderRect(thread_id, input_data, + data_max_color_channel_rect, + image_max_color_channel_rect)); } + return true; } } // namespace jxl |