Flutter Engine
The Flutter Engine
Classes | Namespaces | Macros | Functions
SkWuffsCodec.cpp File Reference
#include "include/codec/SkCodec.h"
#include "include/codec/SkCodecAnimation.h"
#include "include/codec/SkEncodedImageFormat.h"
#include "include/codec/SkGifDecoder.h"
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypes.h"
#include "include/private/SkEncodedInfo.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkTo.h"
#include "modules/skcms/skcms.h"
#include "src/codec/SkCodecPriv.h"
#include "src/codec/SkFrameHolder.h"
#include "src/codec/SkSampler.h"
#include "src/codec/SkScalingCodec.h"
#include "src/core/SkDraw.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkStreamPriv.h"
#include <climits>
#include <cstdint>
#include <cstring>
#include <memory>
#include <utility>
#include <vector>
#include "wuffs-v0.3.c"

Go to the source code of this file.

Classes

class  SkWuffsFrame
 
class  SkWuffsFrameHolder
 
class  SkWuffsCodec
 

Namespaces

namespace  SkGifDecoder
 

Macros

#define SK_WUFFS_CODEC_BUFFER_SIZE   4096
 
#define SK_WUFFS_INITIALIZE_FLAGS   WUFFS_INITIALIZE__DEFAULT_OPTIONS
 

Functions

static bool fill_buffer (wuffs_base__io_buffer *b, SkStream *s)
 
static bool seek_buffer (wuffs_base__io_buffer *b, SkStream *s, uint64_t pos)
 
static SkCodecAnimation::DisposalMethod wuffs_disposal_to_skia_disposal (wuffs_base__animation_disposal w)
 
static SkAlphaType to_alpha_type (bool opaque)
 
static SkCodec::Result reset_and_decode_image_config (wuffs_gif__decoder *decoder, wuffs_base__image_config *imgcfg, wuffs_base__io_buffer *b, SkStream *s)
 
SK_API bool SkGifDecoder::IsGif (const void *, size_t)
 
std::unique_ptr< SkCodecSkGifDecoder::MakeFromStream (std::unique_ptr< SkStream > stream, SkCodec::SelectionPolicy selectionPolicy, SkCodec::Result *result)
 
SK_API std::unique_ptr< SkCodecSkGifDecoder::Decode (std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
 
SK_API std::unique_ptr< SkCodecSkGifDecoder::Decode (sk_sp< SkData >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
 

Macro Definition Documentation

◆ SK_WUFFS_CODEC_BUFFER_SIZE

#define SK_WUFFS_CODEC_BUFFER_SIZE   4096

Definition at line 66 of file SkWuffsCodec.cpp.

◆ SK_WUFFS_INITIALIZE_FLAGS

#define SK_WUFFS_INITIALIZE_FLAGS   WUFFS_INITIALIZE__DEFAULT_OPTIONS

Definition at line 81 of file SkWuffsCodec.cpp.

Function Documentation

◆ fill_buffer()

static bool fill_buffer ( wuffs_base__io_buffer *  b,
SkStream s 
)
static

Definition at line 84 of file SkWuffsCodec.cpp.

84 {
85 b->compact();
86 size_t num_read = s->read(b->data.ptr + b->meta.wi, b->data.len - b->meta.wi);
87 b->meta.wi += num_read;
88 // We hard-code false instead of s->isAtEnd(). In theory, Skia's
89 // SkStream::isAtEnd() method has the same semantics as Wuffs'
90 // wuffs_base__io_buffer_meta::closed field. Specifically, both are false
91 // when reading from a network socket when all bytes *available right now*
92 // have been read but there might be more later.
93 //
94 // However, SkStream is designed around synchronous I/O. The SkStream::read
95 // method does not take a callback and, per its documentation comments, a
96 // read request for N bytes should block until a full N bytes are
97 // available. In practice, Blink's SkStream subclass builds on top of async
98 // I/O and cannot afford to block. While it satisfies "the letter of the
99 // law", in terms of what the C++ compiler needs, it does not satisfy "the
100 // spirit of the law". Its read() can return short without blocking and its
101 // isAtEnd() can return false positives.
102 //
103 // When closed is true, Wuffs treats incomplete input as a fatal error
104 // instead of a recoverable "short read" suspension. We therefore hard-code
105 // false and return kIncompleteInput (instead of kErrorInInput) up the call
106 // stack even if the SkStream isAtEnd. The caller usually has more context
107 // (more than what's in the SkStream) to differentiate the two, like this:
108 // https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.cc;l=115;drc=277dcc4d810ae4c0286d8af96d270ed9b686c5ff
109 b->meta.closed = false;
110 return num_read > 0;
111}
static bool b
struct MyStruct s

◆ reset_and_decode_image_config()

static SkCodec::Result reset_and_decode_image_config ( wuffs_gif__decoder *  decoder,
wuffs_base__image_config *  imgcfg,
wuffs_base__io_buffer *  b,
SkStream s 
)
static

Definition at line 147 of file SkWuffsCodec.cpp.

150 {
151 // Calling decoder->initialize will memset most or all of it to zero,
152 // depending on SK_WUFFS_INITIALIZE_FLAGS.
153 wuffs_base__status status =
154 decoder->initialize(sizeof__wuffs_gif__decoder(), WUFFS_VERSION, SK_WUFFS_INITIALIZE_FLAGS);
155 if (status.repr != nullptr) {
156 SkCodecPrintf("initialize: %s", status.message());
158 }
159
160 // See https://bugs.chromium.org/p/skia/issues/detail?id=12055
161 decoder->set_quirk_enabled(WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA, true);
162
163 while (true) {
164 status = decoder->decode_image_config(imgcfg, b);
165 if (status.repr == nullptr) {
166 break;
167 } else if (status.repr != wuffs_base__suspension__short_read) {
168 SkCodecPrintf("decode_image_config: %s", status.message());
170 } else if (!fill_buffer(b, s)) {
172 }
173 }
174
175 // A GIF image's natural color model is indexed color: 1 byte per pixel,
176 // indexing a 256-element palette.
177 //
178 // For Skia, we override that to decode to 4 bytes per pixel, BGRA or RGBA.
179 uint32_t pixfmt = WUFFS_BASE__PIXEL_FORMAT__INVALID;
180 switch (kN32_SkColorType) {
182 pixfmt = WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL;
183 break;
185 pixfmt = WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL;
186 break;
187 default:
189 }
190 if (imgcfg) {
191 imgcfg->pixcfg.set(pixfmt, WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, imgcfg->pixcfg.width(),
192 imgcfg->pixcfg.height());
193 }
194
195 return SkCodec::kSuccess;
196}
#define SkCodecPrintf(...)
Definition: SkCodecPriv.h:23
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
#define SK_WUFFS_INITIALIZE_FLAGS
static bool fill_buffer(wuffs_base__io_buffer *b, SkStream *s)
@ kIncompleteInput
Definition: SkCodec.h:84
@ kInternalError
Definition: SkCodec.h:118
@ kSuccess
Definition: SkCodec.h:80
@ kErrorInInput
Definition: SkCodec.h:91

◆ seek_buffer()

static bool seek_buffer ( wuffs_base__io_buffer *  b,
SkStream s,
uint64_t  pos 
)
static

Definition at line 113 of file SkWuffsCodec.cpp.

113 {
114 // Try to re-position the io_buffer's meta.ri read-index first, which is
115 // cheaper than seeking in the backing SkStream.
116 if ((pos >= b->meta.pos) && (pos - b->meta.pos <= b->meta.wi)) {
117 b->meta.ri = pos - b->meta.pos;
118 return true;
119 }
120 // Seek in the backing SkStream.
121 if ((pos > SIZE_MAX) || (!s->seek(pos))) {
122 return false;
123 }
124 b->meta.wi = 0;
125 b->meta.ri = 0;
126 b->meta.pos = pos;
127 b->meta.closed = false;
128 return true;
129}
SkPoint pos

◆ to_alpha_type()

static SkAlphaType to_alpha_type ( bool  opaque)
static

Definition at line 143 of file SkWuffsCodec.cpp.

143 {
145}
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29

◆ wuffs_disposal_to_skia_disposal()

static SkCodecAnimation::DisposalMethod wuffs_disposal_to_skia_disposal ( wuffs_base__animation_disposal  w)
static

Definition at line 131 of file SkWuffsCodec.cpp.

132 {
133 switch (w) {
134 case WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND:
136 case WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS:
138 default:
140 }
141}
SkScalar w