blob: 22ec3cd767cbdb2ece6a97464eb41b269b073375 [file] [log] [blame]
/*
* Copyright 2024 Google LLC.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPngRustCodec_DEFINED
#define SkPngRustCodec_DEFINED
#include <memory>
#include <vector>
#include "experimental/rust_png/ffi/FFI.rs.h"
#include "src/codec/SkPngCodecBase.h"
#include "third_party/rust/cxx/v1/cxx.h"
struct SkEncodedInfo;
class SkFrame;
class SkStream;
template <typename T> class SkSpan;
// This class provides the Skia image decoding API (`SkCodec`) on top of:
// * The third-party `png` crate (PNG decompression and decoding implemented in
// Rust)
// * Skia's `SkSwizzler` and `skcms_Transform` (pixel format and color space
// transformations implemented in C++).
class SkPngRustCodec : public SkPngCodecBase {
public:
static std::unique_ptr<SkPngRustCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
// `public` to support `std::make_unique<SkPngRustCodec>(...)`.
SkPngRustCodec(SkEncodedInfo&&, std::unique_ptr<SkStream>, rust::Box<rust_png::Reader>);
~SkPngRustCodec() override;
private:
struct DecodingState {
SkSpan<uint8_t> dst;
size_t dstRowSize; // in bytes.
};
// Helper for validating parameters of `onGetPixels` and/or
// `onStartIncrementalDecode`. If `kSuccess` is returned then
// `decodingState` output parameter got populated.
Result startDecoding(const SkImageInfo& dstInfo,
void* pixels,
size_t rowBytes,
const Options& options,
DecodingState* decodingState);
// Helper for row-by-row decoding which is used from `onGetPixels` and/or
// `onIncrementalDecode`.
Result incrementalDecode(DecodingState& decodingState, int* rowsDecoded);
// Temporary helper for *non*-row-by-row decoding of interlaced images.
//
// TODO(https://crbug.com/356923435): Remove this method after implementing
// row-by-row decoding of interlaced images (see WIP CL at
// http://review.skia.org/894576).
Result decodeInterlacedImage(DecodingState& decodingState);
// SkCodec overrides:
Result onGetPixels(const SkImageInfo& dstInfo,
void* pixels,
size_t rowBytes,
const Options&,
int* rowsDecoded) override;
Result onStartIncrementalDecode(const SkImageInfo& dstInfo,
void* pixels,
size_t rowBytes,
const Options&) override;
Result onIncrementalDecode(int* rowsDecoded) override;
bool onGetFrameInfo(int, FrameInfo*) const override;
// SkPngCodecBase overrides:
std::optional<SkSpan<const PaletteColorEntry>> onTryGetPlteChunk() override;
std::optional<SkSpan<const uint8_t>> onTryGetTrnsChunk() override;
rust::Box<rust_png::Reader> fReader;
std::optional<DecodingState> fIncrementalDecodingState;
class PngFrame;
std::vector<PngFrame> fFrames;
size_t fNumOfFullyReceivedFrames = 0;
};
#endif // SkPngRustCodec_DEFINED