Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/third_party/jpeg-xl/lib/jxl/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 13 kB image not shown  

Quelle  dec_cache.cc   Sprache: C

 
// 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.

#include "lib/jxl/dec_cache.h"

#include <jxl/memory_manager.h>

#include <algorithm>

#include "lib/jxl/ac_strategy.h"
#include "lib/jxl/base/status.h"
#include "lib/jxl/blending.h"
#include "lib/jxl/coeff_order.h"
#include "lib/jxl/common.h"  // JXL_HIGH_PRECISION
#include "lib/jxl/memory_manager_internal.h"
#include "lib/jxl/render_pipeline/stage_blending.h"
#include "lib/jxl/render_pipeline/stage_chroma_upsampling.h"
#include "lib/jxl/render_pipeline/stage_cms.h"
#include "lib/jxl/render_pipeline/stage_epf.h"
#include "lib/jxl/render_pipeline/stage_from_linear.h"
#include "lib/jxl/render_pipeline/stage_gaborish.h"
#include "lib/jxl/render_pipeline/stage_noise.h"
#include "lib/jxl/render_pipeline/stage_patches.h"
#include "lib/jxl/render_pipeline/stage_splines.h"
#include "lib/jxl/render_pipeline/stage_spot.h"
#include "lib/jxl/render_pipeline/stage_to_linear.h"
#include "lib/jxl/render_pipeline/stage_tone_mapping.h"
#include "lib/jxl/render_pipeline/stage_upsampling.h"
#include "lib/jxl/render_pipeline/stage_write.h"
#include "lib/jxl/render_pipeline/stage_xyb.h"
#include "lib/jxl/render_pipeline/stage_ycbcr.h"

namespace jxl {

Status GroupDecCache::InitOnce(JxlMemoryManager* memory_manager,
                               size_t num_passes, size_t used_acs) {
  for (size_t i = 0; i < num_passes; i++) {
    if (num_nzeroes[i].xsize() == 0) {
      // Allocate enough for a whole group - partial groups on the
      // right/bottom border just use a subset. The valid size is passed via
      // Rect.

      JXL_ASSIGN_OR_RETURN(num_nzeroes[i],
                           Image3I::Create(memory_manager, kGroupDimInBlocks,
                                           kGroupDimInBlocks));
    }
  }
  size_t max_block_area = 0;

  for (uint8_t o = 0; o < AcStrategy::kNumValidStrategies; ++o) {
    AcStrategy acs = AcStrategy::FromRawStrategy(o);
    if ((used_acs & (1 << o)) == 0) continue;
    size_t area =
        acs.covered_blocks_x() * acs.covered_blocks_y() * kDCTBlockSize;
    max_block_area = std::max(area, max_block_area);
  }

  if (max_block_area > max_block_area_) {
    max_block_area_ = max_block_area;
    // We need 3x float blocks for dequantized coefficients and 1x for scratch
    // space for transforms.
    JXL_ASSIGN_OR_RETURN(
        float_memory_,
        AlignedMemory::Create(memory_manager,
                              max_block_area_ * 7 * sizeof(float)));
    // We need 3x int32 or int16 blocks for quantized coefficients.
    JXL_ASSIGN_OR_RETURN(
        int32_memory_,
        AlignedMemory::Create(memory_manager,
                              max_block_area_ * 3 * sizeof(int32_t)));
    JXL_ASSIGN_OR_RETURN(
        int16_memory_,
        AlignedMemory::Create(memory_manager,
                              max_block_area_ * 3 * sizeof(int16_t)));
  }

  dec_group_block = float_memory_.address<float>();
  scratch_space = dec_group_block + max_block_area_ * 3;
  dec_group_qblock = int32_memory_.address<int32_t>();
  dec_group_qblock16 = int16_memory_.address<int16_t>();
  return true;
}

// Initialize the decoder state after all of DC is decoded.
Status PassesDecoderState::InitForAC(size_t num_passes, ThreadPool* pool) {
  shared_storage.coeff_order_size = 0;
  for (uint8_t o = 0; o < AcStrategy::kNumValidStrategies; ++o) {
    if (((1 << o) & used_acs) == 0) continue;
    uint8_t ord = kStrategyOrder[o];
    shared_storage.coeff_order_size =
        std::max(kCoeffOrderOffset[3 * (ord + 1)] * kDCTBlockSize,
                 shared_storage.coeff_order_size);
  }
  size_t sz = num_passes * shared_storage.coeff_order_size;
  if (sz > shared_storage.coeff_orders.size()) {
    shared_storage.coeff_orders.resize(sz);
  }
  return true;
}

Status PassesDecoderState::PreparePipeline(const FrameHeader& frame_header,
                                           const ImageMetadata* metadata,
                                           ImageBundle* decoded,
                                           PipelineOptions options) {
  JxlMemoryManager* memory_manager = this->memory_manager();
  size_t num_c = 3 + frame_header.nonserialized_metadata->m.num_extra_channels;
  bool render_noise =
      (options.render_noise && (frame_header.flags & FrameHeader::kNoise) != 0);
  size_t num_tmp_c = render_noise ? 3 : 0;

  if (frame_header.CanBeReferenced()) {
    // Necessary so that SetInputSizes() can allocate output buffers as needed.
    frame_storage_for_referencing = ImageBundle(memory_manager, metadata);
  }

  RenderPipeline::Builder builder(memory_manager, num_c + num_tmp_c);

  if (options.use_slow_render_pipeline) {
    builder.UseSimpleImplementation();
  }

  if (!frame_header.chroma_subsampling.Is444()) {
    for (size_t c = 0; c < 3; c++) {
      if (frame_header.chroma_subsampling.HShift(c) != 0) {
        JXL_RETURN_IF_ERROR(
            builder.AddStage(GetChromaUpsamplingStage(c, /*horizontal=*/true)));
      }
      if (frame_header.chroma_subsampling.VShift(c) != 0) {
        JXL_RETURN_IF_ERROR(builder.AddStage(
            GetChromaUpsamplingStage(c, /*horizontal=*/false)));
      }
    }
  }

  if (frame_header.loop_filter.gab) {
    JXL_RETURN_IF_ERROR(
        builder.AddStage(GetGaborishStage(frame_header.loop_filter)));
  }

  {
    const LoopFilter& lf = frame_header.loop_filter;
    if (lf.epf_iters >= 3) {
      JXL_RETURN_IF_ERROR(
          builder.AddStage(GetEPFStage(lf, sigma, EpfStage::Zero)));
    }
    if (lf.epf_iters >= 1) {
      JXL_RETURN_IF_ERROR(
          builder.AddStage(GetEPFStage(lf, sigma, EpfStage::One)));
    }
    if (lf.epf_iters >= 2) {
      JXL_RETURN_IF_ERROR(
          builder.AddStage(GetEPFStage(lf, sigma, EpfStage::Two)));
    }
  }

  bool late_ec_upsample = frame_header.upsampling != 1;
  for (auto ecups : frame_header.extra_channel_upsampling) {
    if (ecups != frame_header.upsampling) {
      // If patches are applied, either frame_header.upsampling == 1 or
      // late_ec_upsample is true.
      late_ec_upsample = false;
    }
  }

  if (!late_ec_upsample) {
    for (size_t ec = 0; ec < frame_header.extra_channel_upsampling.size();
         ec++) {
      if (frame_header.extra_channel_upsampling[ec] != 1) {
        JXL_RETURN_IF_ERROR(builder.AddStage(GetUpsamplingStage(
            frame_header.nonserialized_metadata->transform_data, 3 + ec,
            CeilLog2Nonzero(frame_header.extra_channel_upsampling[ec]))));
      }
    }
  }

  if ((frame_header.flags & FrameHeader::kPatches) != 0) {
    JXL_RETURN_IF_ERROR(builder.AddStage(GetPatchesStage(
        &shared->image_features.patches,
        &frame_header.nonserialized_metadata->m.extra_channel_info)));
  }
  if ((frame_header.flags & FrameHeader::kSplines) != 0) {
    JXL_RETURN_IF_ERROR(
        builder.AddStage(GetSplineStage(&shared->image_features.splines)));
  }

  if (frame_header.upsampling != 1) {
    size_t nb_channels =
        3 +
        (late_ec_upsample ? frame_header.extra_channel_upsampling.size() : 0);
    for (size_t c = 0; c < nb_channels; c++) {
      JXL_RETURN_IF_ERROR(builder.AddStage(GetUpsamplingStage(
          frame_header.nonserialized_metadata->transform_data, c,
          CeilLog2Nonzero(frame_header.upsampling))));
    }
  }
  if (render_noise) {
    JXL_RETURN_IF_ERROR(builder.AddStage(GetConvolveNoiseStage(num_c)));
    JXL_RETURN_IF_ERROR(builder.AddStage(GetAddNoiseStage(
        shared->image_features.noise_params, shared->cmap.base(), num_c)));
  }
  if (frame_header.dc_level != 0) {
    JXL_RETURN_IF_ERROR(builder.AddStage(GetWriteToImage3FStage(
        memory_manager, &shared_storage.dc_frames[frame_header.dc_level - 1])));
  }

  if (frame_header.CanBeReferenced() &&
      frame_header.save_before_color_transform) {
    JXL_RETURN_IF_ERROR(builder.AddStage(GetWriteToImageBundleStage(
        &frame_storage_for_referencing, output_encoding_info)));
  }

  bool has_alpha = false;
  size_t alpha_c = 0;
  for (size_t i = 0; i < metadata->extra_channel_info.size(); i++) {
    if (metadata->extra_channel_info[i].type == ExtraChannel::kAlpha) {
      has_alpha = true;
      alpha_c = 3 + i;
      break;
    }
  }

  if (fast_xyb_srgb8_conversion) {
#if !JXL_HIGH_PRECISION
    JXL_ENSURE(!NeedsBlending(frame_header));
    JXL_ENSURE(!frame_header.CanBeReferenced() ||
               frame_header.save_before_color_transform);
    JXL_ENSURE(!options.render_spotcolors ||
               !metadata->Find(ExtraChannel::kSpotColor));
    bool is_rgba = (main_output.format.num_channels == 4);
    uint8_t* rgb_output = reinterpret_cast<uint8_t*>(main_output.buffer);
    JXL_RETURN_IF_ERROR(builder.AddStage(
        GetFastXYBTosRGB8Stage(rgb_output, main_output.stride, width, height,
                               is_rgba, has_alpha, alpha_c)));
#endif
  } else {
    bool linear = false;
    if (frame_header.color_transform == ColorTransform::kYCbCr) {
      JXL_RETURN_IF_ERROR(builder.AddStage(GetYCbCrStage()));
    } else if (frame_header.color_transform == ColorTransform::kXYB) {
      JXL_RETURN_IF_ERROR(builder.AddStage(GetXYBStage(output_encoding_info)));
      if (output_encoding_info.color_encoding.GetColorSpace() !=
          ColorSpace::kXYB) {
        linear = true;
      }
    }  // Nothing to do for kNone.

    if (options.coalescing && NeedsBlending(frame_header)) {
      if (linear) {
        JXL_RETURN_IF_ERROR(
            builder.AddStage(GetFromLinearStage(output_encoding_info)));
        linear = false;
      }
      JXL_RETURN_IF_ERROR(builder.AddStage(GetBlendingStage(
          frame_header, this, output_encoding_info.color_encoding)));
    }

    if (options.coalescing && frame_header.CanBeReferenced() &&
        !frame_header.save_before_color_transform) {
      if (linear) {
        JXL_RETURN_IF_ERROR(
            builder.AddStage(GetFromLinearStage(output_encoding_info)));
        linear = false;
      }
      JXL_RETURN_IF_ERROR(builder.AddStage(GetWriteToImageBundleStage(
          &frame_storage_for_referencing, output_encoding_info)));
    }

    if (options.render_spotcolors &&
        frame_header.nonserialized_metadata->m.Find(ExtraChannel::kSpotColor)) {
      for (size_t i = 0; i < metadata->extra_channel_info.size(); i++) {
        // Don't use Find() because there may be multiple spot color channels.
        const ExtraChannelInfo& eci = metadata->extra_channel_info[i];
        if (eci.type == ExtraChannel::kSpotColor) {
          JXL_RETURN_IF_ERROR(
              builder.AddStage(GetSpotColorStage(i, eci.spot_color)));
        }
      }
    }

    auto tone_mapping_stage = GetToneMappingStage(output_encoding_info);
    if (tone_mapping_stage) {
      if (!linear) {
        auto to_linear_stage = GetToLinearStage(output_encoding_info);
        if (!to_linear_stage) {
          if (!output_encoding_info.cms_set) {
            return JXL_FAILURE("Cannot tonemap this colorspace without a CMS");
          }
          auto cms_stage = GetCmsStage(output_encoding_info);
          if (cms_stage) {
            JXL_RETURN_IF_ERROR(builder.AddStage(std::move(cms_stage)));
          }
        } else {
          JXL_RETURN_IF_ERROR(builder.AddStage(std::move(to_linear_stage)));
        }
        linear = true;
      }
      JXL_RETURN_IF_ERROR(builder.AddStage(std::move(tone_mapping_stage)));
    }

    if (linear) {
      const size_t channels_src =
          (output_encoding_info.orig_color_encoding.IsCMYK()
               ? 4
               : output_encoding_info.orig_color_encoding.Channels());
      const size_t channels_dst =
          output_encoding_info.color_encoding.Channels();
      bool mixing_color_and_grey = (channels_dst != channels_src);
      if ((output_encoding_info.color_encoding_is_original) ||
          (!output_encoding_info.cms_set) || mixing_color_and_grey) {
        // in those cases we only need a linear stage in other cases we attempt
        // to obtain a cms stage: the cases are
        // - output_encoding_info.color_encoding_is_original: no cms stage
        // needed because it would be a no-op
        // - !output_encoding_info.cms_set: can't use the cms, so no point in
        // trying to add a cms stage
        // - mixing_color_and_grey: cms stage can't handle that
        // TODO(firsching): remove "mixing_color_and_grey" condition after
        // adding support for greyscale to cms stage.
        JXL_RETURN_IF_ERROR(
            builder.AddStage(GetFromLinearStage(output_encoding_info)));
      } else {
        if (!output_encoding_info.linear_color_encoding.CreateICC()) {
          return JXL_FAILURE("Failed to create ICC");
        }
        auto cms_stage = GetCmsStage(output_encoding_info);
        if (cms_stage) {
          JXL_RETURN_IF_ERROR(builder.AddStage(std::move(cms_stage)));
        }
      }
      linear = false;
    }
    (void)linear;

    if (main_output.callback.IsPresent() || main_output.buffer) {
      JXL_RETURN_IF_ERROR(builder.AddStage(GetWriteToOutputStage(
          main_output, width, height, has_alpha, unpremul_alpha, alpha_c,
          undo_orientation, extra_output, memory_manager)));
    } else {
      JXL_RETURN_IF_ERROR(builder.AddStage(
          GetWriteToImageBundleStage(decoded, output_encoding_info)));
    }
  }
  JXL_ASSIGN_OR_RETURN(render_pipeline,
                       std::move(builder).Finalize(shared->frame_dim));
  return render_pipeline->IsInitialized();
}

}  // namespace jxl

Messung V0.5
C=92 H=95 G=93

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.