File: crabbyavif_image_decoder.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (199 lines) | stat: -rw-r--r-- 8,503 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// WARNING: Auto-generated by gen_crabbyavif_wrapper.py.
// Do not modify manually.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_DECODERS_AVIF_CRABBYAVIF_IMAGE_DECODER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_DECODERS_AVIF_CRABBYAVIF_IMAGE_DECODER_H_

#include <memory>
#include <vector>

#include "base/functional/callback.h"
#include "third_party/blink/renderer/platform/allow_discouraged_type.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/crabbyavif/src/include/avif/avif.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/point.h"

namespace blink {

class FastSharedBufferReader;

class PLATFORM_EXPORT CrabbyAVIFImageDecoder final : public ImageDecoder {
 public:
  CrabbyAVIFImageDecoder(AlphaOption,
                         HighBitDepthDecodingOption,
                         ColorBehavior,
                         cc::AuxImage,
                         wtf_size_t max_decoded_bytes,
                         AnimationOption);
  CrabbyAVIFImageDecoder(const CrabbyAVIFImageDecoder&) = delete;
  CrabbyAVIFImageDecoder& operator=(const CrabbyAVIFImageDecoder&) = delete;
  ~CrabbyAVIFImageDecoder() override;

  // ImageDecoder:
  String FilenameExtension() const override;
  const AtomicString& MimeType() const override;
  bool ImageIsHighBitDepth() override;
  void OnSetData(scoped_refptr<SegmentReader> data) override;
  bool GetGainmapInfoAndData(
      SkGainmapInfo& out_gainmap_info,
      scoped_refptr<SegmentReader>& out_gainmap_data) const override;
  cc::YUVSubsampling GetYUVSubsampling() const override;
  gfx::Size DecodedYUVSize(cc::YUVIndex) const override;
  wtf_size_t DecodedYUVWidthBytes(cc::YUVIndex) const override;
  SkYUVColorSpace GetYUVColorSpace() const override;
  uint8_t GetYUVBitDepth() const override;
  std::optional<gfx::HDRMetadata> GetHDRMetadata() const override;
  void DecodeToYUV() override;
  int RepetitionCount() const override;
  bool FrameIsReceivedAtIndex(wtf_size_t) const override;
  std::optional<base::TimeDelta> FrameTimestampAtIndex(
      wtf_size_t) const override;
  base::TimeDelta FrameDurationAtIndex(wtf_size_t) const override;
  bool ImageHasBothStillAndAnimatedSubImages() const override;

  // Returns true if the data in fast_reader begins with a valid FileTypeBox
  // (ftyp) that supports the brand 'avif' or 'avis'.
  static bool MatchesAVIFSignature(const FastSharedBufferReader& fast_reader);

  gfx::ColorSpace GetColorSpaceForTesting() const;

 private:
  // If the AVIF image has a clean aperture ('clap') property, what kind of
  // clean aperture it is. Values synced with 'AVIFCleanApertureType' in
  // src/tools/metrics/histograms/enums.xml.
  //
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class AVIFCleanApertureType {
    kInvalid = 0,        // The clean aperture property is invalid.
    kNonzeroOrigin = 1,  // The origin of the clean aperture is not (0, 0).
    kZeroOrigin = 2,     // The origin of the clean aperture is (0, 0).
    kMaxValue = kZeroOrigin,
  };

  struct AvifIOData {
    AvifIOData();
    AvifIOData(scoped_refptr<const SegmentReader> reader,
               bool all_data_received);
    ~AvifIOData();

    scoped_refptr<const SegmentReader> reader;
    std::vector<uint8_t> buffer ALLOW_DISCOURAGED_TYPE("Required by libavif");
    bool all_data_received = false;
  };

  void ParseMetadata();

  // ImageDecoder:
  void DecodeSize() override;
  wtf_size_t DecodeFrameCount() override;
  void InitializeNewFrame(wtf_size_t) override;
  void Decode(wtf_size_t) override;
  bool CanReusePreviousFrameBuffer(wtf_size_t) const override;

  // Implements crabbyavif::avifIOReadFunc, the |read| function in the
  // crabbyavif::avifIO struct.
  static crabbyavif::avifResult ReadFromSegmentReader(
      crabbyavif::avifIO* io,
      uint32_t read_flags,
      uint64_t offset,
      size_t size,
      crabbyavif::avifROData* out);

  // Creates |decoder_| if not yet created and decodes the size and frame count.
  bool UpdateDemuxer();

  // Decodes the frame at index |index| and checks if the frame's size, bit
  // depth, and YUV format matches those reported by the container. The decoded
  // frame is available in decoded_image_.
  crabbyavif::avifResult DecodeImage(wtf_size_t index);

  // Crops |decoded_image_|.
  void CropDecodedImage();

  // Renders the rows [from_row, *to_row) of |image| to |buffer|. Returns
  // whether |image| was rendered successfully. On return, the in/out argument
  // |*to_row| may be decremented in case of subsampled chroma needing more
  // data.
  bool RenderImage(const crabbyavif::avifImage* image,
                   int from_row,
                   int* to_row,
                   ImageFrame* buffer);

  // Applies color profile correction to the rows [from_row, to_row) of
  // |buffer|, if desired.
  void ColorCorrectImage(int from_row, int to_row, ImageFrame* buffer);

  // Returns decoder_->image or decoder_->image->gainMap->image depending on
  // aux_image_. May be nullptr if requesting the gain map image
  // (cc::AuxImage::kGainmap) but no gain map is present.
  crabbyavif::avifImage* GetDecoderImage() const;

  bool have_parsed_current_data_ = false;
  // The image width and height (before cropping, if any) from the container.
  //
  // Note: container_width_, container_height_, decoder_->image->width, and
  // decoder_->image->height are the width and height of the full image. Size()
  // returns the size of the cropped image (the clean aperture).
  uint32_t container_width_ = 0;
  uint32_t container_height_ = 0;
  // The bit depth from the container.
  uint8_t bit_depth_ = 0;
  bool decode_to_half_float_ = false;
  uint8_t chroma_shift_x_ = 0;
  uint8_t chroma_shift_y_ = 0;
  std::optional<gfx::HDRMetadata> hdr_metadata_;
  bool progressive_ = false;
  // Number of displayed rows for a non-progressive still image.
  int incrementally_displayed_height_ = 0;
  // The YUV format from the container.
  crabbyavif::avifPixelFormat avif_yuv_format_ =
      crabbyavif::AVIF_PIXEL_FORMAT_NONE;
  wtf_size_t decoded_frame_count_ = 0;
  SkYUVColorSpace yuv_color_space_ = SkYUVColorSpace::kIdentity_SkYUVColorSpace;
  // Used to call UpdateBppHistogram<"Avif">() at most once to record the
  // bits-per-pixel value of the image when the image is successfully decoded.
  base::OnceCallback<void(gfx::Size, size_t)> update_bpp_histogram_callback_;
  std::optional<AVIFCleanApertureType> clap_type_;
  // Whether the 'clap' (clean aperture) property should be ignored, e.g.
  // because the 'clap' property is invalid or unsupported.
  bool ignore_clap_ = false;
  // The origin (top left corner) of the clean aperture. Used only when the
  // image has a valid 'clap' (clean aperture) property.
  gfx::Point clap_origin_;
  // A copy of decoder_->image with the width, height, and plane buffers
  // adjusted to those of the clean aperture. Used only when the image has a
  // 'clap' (clean aperture) property.
  std::unique_ptr<crabbyavif::avifImage,
                  decltype(&crabbyavif::crabby_avifImageDestroy)>
      cropped_image_{nullptr, crabbyavif::crabby_avifImageDestroy};
  // Set by a successful DecodeImage() call to either decoder_->image or
  // cropped_image_.get() depending on whether the image has a 'clap' (clean
  // aperture) property.
  raw_ptr<const crabbyavif::avifImage, DanglingUntriaged> decoded_image_ =
      nullptr;
  // The declaration order of the next three fields is important. decoder_
  // points to avif_io_, and avif_io_ points to avif_io_data_. The destructor
  // must destroy them in that order.
  AvifIOData avif_io_data_;
  crabbyavif::avifIO avif_io_ = {};
  std::unique_ptr<crabbyavif::avifDecoder,
                  decltype(&crabbyavif::crabby_avifDecoderDestroy)>
      decoder_{nullptr, crabbyavif::crabby_avifDecoderDestroy};

  const AnimationOption animation_option_;

  // Used temporarily for incremental decoding and for some YUV to RGB color
  // conversions.
  Vector<uint8_t> previous_last_decoded_row_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_DECODERS_AVIF_CRABBYAVIF_IMAGE_DECODER_H_