#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include <memory>
#include "base/containers/heap_array.h"
#include "base/logging.h"
#include "base/numerics/byte_conversions.h"
#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "media/media_buildflags.h"
#include "skia/ext/cicp.h"
#include "third_party/blink/public/common/buildflags.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder.h"
#include "third_party/blink/renderer/platform/image-decoders/fast_shared_buffer_reader.h"
#include "third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.h"
#include "third_party/blink/renderer/platform/image-decoders/ico/ico_image_decoder.h"
#include "third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h"
#include "third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h"
#include "third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/private/SkExif.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_conversions.h"
#if BUILDFLAG(ENABLE_AV1_DECODER)
#include "third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h"
#include "third_party/blink/renderer/platform/image-decoders/avif/crabbyavif_image_decoder.h"
#endif
namespace blink {
namespace {
cc::ImageType FileExtensionToImageType(String image_extension) { … }
wtf_size_t CalculateMaxDecodedBytes(
ImageDecoder::HighBitDepthDecodingOption high_bit_depth_decoding_option,
const SkISize& desired_size,
size_t platform_max_decoded_bytes) { … }
gfx::Size ExtractDensityCorrectedSize(const SkExif::Metadata& metadata,
const gfx::Size& physical_size) { … }
inline bool MatchesJPEGSignature(const char* contents) { … }
inline bool MatchesPNGSignature(const char* contents) { … }
inline bool MatchesGIFSignature(const char* contents) { … }
inline bool MatchesWebPSignature(const char* contents) { … }
inline bool MatchesICOSignature(const char* contents) { … }
inline bool MatchesCURSignature(const char* contents) { … }
inline bool MatchesBMPSignature(const char* contents) { … }
constexpr wtf_size_t kLongestSignatureLength = …;
String SniffMimeTypeInternal(scoped_refptr<SegmentReader> reader) { … }
bool IsLossyImageMIMEType(const String& mime_type) { … }
bool IsLosslessImageMIMEType(const String& mime_type) { … }
}
ImageDecoder::ImageDecoder(
AlphaOption alpha_option,
HighBitDepthDecodingOption high_bit_depth_decoding_option,
ColorBehavior color_behavior,
cc::AuxImage aux_image,
wtf_size_t max_decoded_bytes)
: … { … }
ImageDecoder::~ImageDecoder() = default;
std::unique_ptr<ImageDecoder> ImageDecoder::Create(
scoped_refptr<SegmentReader> data,
bool data_complete,
AlphaOption alpha_option,
HighBitDepthDecodingOption high_bit_depth_decoding_option,
ColorBehavior color_behavior,
cc::AuxImage aux_image,
size_t platform_max_decoded_bytes,
const SkISize& desired_size,
AnimationOption animation_option) { … }
std::unique_ptr<ImageDecoder> ImageDecoder::CreateByMimeType(
String mime_type,
scoped_refptr<SegmentReader> data,
bool data_complete,
AlphaOption alpha_option,
HighBitDepthDecodingOption high_bit_depth_decoding_option,
ColorBehavior color_behavior,
cc::AuxImage aux_image,
size_t platform_max_decoded_bytes,
const SkISize& desired_size,
AnimationOption animation_option) { … }
bool ImageDecoder::IsAllDataReceived() const { … }
bool ImageDecoder::ImageIsHighBitDepth() { … }
bool ImageDecoder::HasSufficientDataToSniffMimeType(const SharedBuffer& data) { … }
String ImageDecoder::SniffMimeType(scoped_refptr<SharedBuffer> image_data) { … }
ImageDecoder::CompressionFormat ImageDecoder::GetCompressionFormat(
scoped_refptr<SharedBuffer> image_data,
String mime_type) { … }
bool ImageDecoder::IsSizeAvailable() { … }
gfx::Size ImageDecoder::Size() const { … }
Vector<SkISize> ImageDecoder::GetSupportedDecodeSizes() const { … }
bool ImageDecoder::GetGainmapInfoAndData(
SkGainmapInfo& out_gainmap_info,
scoped_refptr<SegmentReader>& out_gainmap_data) const { … }
gfx::Size ImageDecoder::DecodedSize() const { … }
cc::YUVSubsampling ImageDecoder::GetYUVSubsampling() const { … }
gfx::Size ImageDecoder::DecodedYUVSize(cc::YUVIndex) const { … }
wtf_size_t ImageDecoder::DecodedYUVWidthBytes(cc::YUVIndex) const { … }
SkYUVColorSpace ImageDecoder::GetYUVColorSpace() const { … }
uint8_t ImageDecoder::GetYUVBitDepth() const { … }
std::optional<gfx::HDRMetadata> ImageDecoder::GetHDRMetadata() const { … }
gfx::Size ImageDecoder::FrameSizeAtIndex(wtf_size_t) const { … }
cc::ImageHeaderMetadata ImageDecoder::MakeMetadataForDecodeAcceleration()
const { … }
bool ImageDecoder::SetSize(unsigned width, unsigned height) { … }
wtf_size_t ImageDecoder::FrameCount() { … }
int ImageDecoder::RepetitionCount() const { … }
ImageFrame* ImageDecoder::DecodeFrameBufferAtIndex(wtf_size_t index) { … }
bool ImageDecoder::FrameHasAlphaAtIndex(wtf_size_t index) const { … }
bool ImageDecoder::FrameIsReceivedAtIndex(wtf_size_t index) const { … }
bool ImageDecoder::FrameIsDecodedAtIndex(wtf_size_t index) const { … }
std::optional<base::TimeDelta> ImageDecoder::FrameTimestampAtIndex(
wtf_size_t) const { … }
base::TimeDelta ImageDecoder::FrameDurationAtIndex(wtf_size_t) const { … }
wtf_size_t ImageDecoder::FrameBytesAtIndex(wtf_size_t index) const { … }
bool ImageDecoder::SetFailed() { … }
wtf_size_t ImageDecoder::ClearCacheExceptFrame(wtf_size_t clear_except_frame) { … }
bool ImageDecoder::HotSpot(gfx::Point&) const { … }
void ImageDecoder::SetMemoryAllocator(SkBitmap::Allocator* allocator) { … }
void ImageDecoder::DecodeToYUV() { … }
bool ImageDecoder::ImageHasBothStillAndAnimatedSubImages() const { … }
wtf_size_t ImageDecoder::ClearCacheExceptTwoFrames(
wtf_size_t clear_except_frame1,
wtf_size_t clear_except_frame2) { … }
void ImageDecoder::ClearFrameBuffer(wtf_size_t frame_index) { … }
wtf_size_t ImageDecoder::DecodeFrameCount() { … }
Vector<wtf_size_t> ImageDecoder::FindFramesToDecode(wtf_size_t index) const { … }
bool ImageDecoder::PostDecodeProcessing(wtf_size_t index) { … }
void ImageDecoder::CorrectAlphaWhenFrameBufferSawNoAlpha(wtf_size_t index) { … }
bool ImageDecoder::InitFrameBuffer(wtf_size_t frame_index) { … }
void ImageDecoder::UpdateAggressivePurging(wtf_size_t index) { … }
bool ImageDecoder::FrameStatusSufficientForSuccessors(wtf_size_t index) { … }
wtf_size_t ImageDecoder::FindRequiredPreviousFrame(wtf_size_t frame_index,
bool frame_rect_is_opaque) { … }
void ImageDecoder::ApplyExifMetadata(const SkData* exif_data,
const gfx::Size& physical_size) { … }
ImagePlanes::ImagePlanes() { … }
ImagePlanes::ImagePlanes(void* planes[cc::kNumYUVPlanes],
const wtf_size_t row_bytes[cc::kNumYUVPlanes],
SkColorType color_type)
: … { … }
void* ImagePlanes::Plane(cc::YUVIndex index) { … }
wtf_size_t ImagePlanes::RowBytes(cc::YUVIndex index) const { … }
ColorProfile::ColorProfile(const skcms_ICCProfile& profile,
base::HeapArray<uint8_t> buffer)
: … { … }
ColorProfile::~ColorProfile() = default;
std::unique_ptr<ColorProfile> ColorProfile::Create(
base::span<const uint8_t> buffer) { … }
ColorProfileTransform::ColorProfileTransform(
const skcms_ICCProfile* src_profile,
const skcms_ICCProfile* dst_profile) { … }
const skcms_ICCProfile* ColorProfileTransform::SrcProfile() const { … }
const skcms_ICCProfile* ColorProfileTransform::DstProfile() const { … }
void ImageDecoder::SetEmbeddedColorProfile(
std::unique_ptr<ColorProfile> profile) { … }
ColorProfileTransform* ImageDecoder::ColorTransform() { … }
ColorProfileTransform::~ColorProfileTransform() = default;
sk_sp<SkColorSpace> ImageDecoder::ColorSpaceForSkImages() { … }
void ImageDecoder::UpdateSkImageColorSpaceAndTransform() { … }
bool ImageDecoder::CanReusePreviousFrameBuffer(wtf_size_t) const { … }
}