chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h"

#include <stdint.h>
#include <string.h>

#include <algorithm>
#include <memory>
#include <optional>
#include <utility>

#include "base/bits.h"
#include "base/containers/adapters.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
#include "base/timer/elapsed_timer.h"
#include "build/build_config.h"
#include "cc/base/math_util.h"
#include "media/base/video_color_space.h"
#include "skia/ext/cicp.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/image-decoders/fast_shared_buffer_reader.h"
#include "third_party/blink/renderer/platform/image-decoders/image_animation.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/image-decoders/rw_buffer.h"
#include "third_party/libavif/src/include/avif/avif.h"
#include "third_party/libavifinfo/src/avifinfo.h"
#include "third_party/libyuv/include/libyuv.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkTypes.h"
#include "third_party/skia/include/private/SkXmp.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/icc_profile.h"

#if defined(ARCH_CPU_BIG_ENDIAN)
#error Blink assumes a little-endian target.
#endif

namespace blink {

namespace {

// The maximum AVIF file size we are willing to decode. This helps libavif
// detect invalid sizes and offsets in an AVIF file before the file size is
// known.
constexpr uint64_t kMaxAvifFileSize =;  // 256 MB

const char* AvifDecoderErrorMessage(const avifDecoder* decoder) {}

// Builds a gfx::ColorSpace from the ITU-T H.273 (CICP) color description.
gfx::ColorSpace GetColorSpace(
    avifColorPrimaries color_primaries,
    avifTransferCharacteristics transfer_characteristics,
    avifMatrixCoefficients matrix_coefficients,
    avifRange yuv_range,
    bool grayscale) {}

// Builds a gfx::ColorSpace from the ITU-T H.273 (CICP) color description in the
// image.
gfx::ColorSpace GetColorSpace(const avifImage* image) {}

// |y_size| is the width or height of the Y plane. Returns the width or height
// of the U and V planes. |chroma_shift| represents the subsampling of the
// chroma (U and V) planes in the x (for width) or y (for height) direction.
int UVSize(int y_size, int chroma_shift) {}

// Creates a copy of the given input (AVIF image data), with the primary item id
// changed so that it now points to the gain map image.
scoped_refptr<SegmentReader> CreateGainmapSegmentReader(
    const AvifInfoFeatures& features,
    const SegmentReader* input) {}

// Stream object for use with libavifinfo.
struct AvifInfoSegmentReaderStream {};

// Stream reading function for use with libavifinfo.
const uint8_t* AvifInfoSegmentReaderRead(void* void_stream, size_t num_bytes) {}

void AvifInfoSegmentReaderSkip(void* void_stream, size_t num_bytes) {}

float FractionToFloat(auto numerator, uint32_t denominator) {
  // First cast to double and not float because uint32_t->float conversion can
  // cause precision loss.
  return static_cast<double>(numerator) / denominator;
}

// If the image has a gain map, returns the alternate image's color space, if
// it's different from the base image's and can be converted to a SkColorSpace.
// If the alternate image color space is the same as the base image, there is no
// need to specify it in SkGainmapInfo, and using the base image's color space
// may be more accurate if the profile cannot be exactly represented as a
// SkColorSpace object.
sk_sp<SkColorSpace> GetAltImageColorSpace(const avifImage& image) {}

}  // namespace

AVIFImageDecoder::AVIFImageDecoder(AlphaOption alpha_option,
                                   HighBitDepthDecodingOption hbd_option,
                                   ColorBehavior color_behavior,
                                   wtf_size_t max_decoded_bytes,
                                   AnimationOption animation_option)
    :{}

AVIFImageDecoder::~AVIFImageDecoder() = default;

String AVIFImageDecoder::FilenameExtension() const {}

const AtomicString& AVIFImageDecoder::MimeType() const {}

bool AVIFImageDecoder::ImageIsHighBitDepth() {}

void AVIFImageDecoder::OnSetData(scoped_refptr<SegmentReader> data) {}

cc::YUVSubsampling AVIFImageDecoder::GetYUVSubsampling() const {}

gfx::Size AVIFImageDecoder::DecodedYUVSize(cc::YUVIndex index) const {}

wtf_size_t AVIFImageDecoder::DecodedYUVWidthBytes(cc::YUVIndex index) const {}

SkYUVColorSpace AVIFImageDecoder::GetYUVColorSpace() const {}

uint8_t AVIFImageDecoder::GetYUVBitDepth() const {}

std::optional<gfx::HDRMetadata> AVIFImageDecoder::GetHDRMetadata() const {}

void AVIFImageDecoder::DecodeToYUV() {}

int AVIFImageDecoder::RepetitionCount() const {}

bool AVIFImageDecoder::FrameIsReceivedAtIndex(wtf_size_t index) const {}

std::optional<base::TimeDelta> AVIFImageDecoder::FrameTimestampAtIndex(
    wtf_size_t index) const {}

base::TimeDelta AVIFImageDecoder::FrameDurationAtIndex(wtf_size_t index) const {}

bool AVIFImageDecoder::ImageHasBothStillAndAnimatedSubImages() const {}

// static
bool AVIFImageDecoder::MatchesAVIFSignature(
    const FastSharedBufferReader& fast_reader) {}

gfx::ColorSpace AVIFImageDecoder::GetColorSpaceForTesting() const {}

void AVIFImageDecoder::ParseMetadata() {}

void AVIFImageDecoder::DecodeSize() {}

wtf_size_t AVIFImageDecoder::DecodeFrameCount() {}

void AVIFImageDecoder::InitializeNewFrame(wtf_size_t index) {}

void AVIFImageDecoder::Decode(wtf_size_t index) {}

bool AVIFImageDecoder::CanReusePreviousFrameBuffer(wtf_size_t index) const {}

// static
avifResult AVIFImageDecoder::ReadFromSegmentReader(avifIO* io,
                                                   uint32_t read_flags,
                                                   uint64_t offset,
                                                   size_t size,
                                                   avifROData* out) {}

bool AVIFImageDecoder::UpdateDemuxer() {}

avifResult AVIFImageDecoder::DecodeImage(wtf_size_t index) {}

void AVIFImageDecoder::CropDecodedImage() {}

bool AVIFImageDecoder::RenderImage(const avifImage* image,
                                   int from_row,
                                   int* to_row,
                                   ImageFrame* buffer) {}

void AVIFImageDecoder::ColorCorrectImage(int from_row,
                                         int to_row,
                                         ImageFrame* buffer) {}

bool AVIFImageDecoder::GetGainmapInfoAndData(
    SkGainmapInfo& out_gainmap_info,
    scoped_refptr<SegmentReader>& out_gainmap_data) const {}

AVIFImageDecoder::AvifIOData::AvifIOData() = default;
AVIFImageDecoder::AvifIOData::AvifIOData(
    scoped_refptr<const SegmentReader> reader,
    bool all_data_received)
    :{}
AVIFImageDecoder::AvifIOData::~AvifIOData() = default;

}  // namespace blink