| /* | |
| * 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 SkPngRustEncoderImpl_DEFINED | |
| #define SkPngRustEncoderImpl_DEFINED | |
| #include <memory> | |
| #include "rust/png/FFI.rs.h" | |
| #include "src/encode/SkPngEncoderBase.h" | |
| #include "third_party/rust/cxx/v1/cxx.h" | |
| class SkWStream; | |
| struct SkEncodedInfo; | |
| class SkPixmap; | |
| class SkPngEncoderMgr; | |
| template <typename T> class SkSpan; | |
| namespace SkPngRustEncoder { | |
| struct Options; | |
| } // namespace SkPngRustEncoder | |
| // This class provides the Skia image encoding API (`SkEncoder`) on top of the | |
| // third-party `png` crate (PNG compression and encoding implemented in Rust). | |
| class SkPngRustEncoderImpl final : public SkPngEncoderBase { | |
| public: | |
| enum ExtraRowTransform { | |
| // `kNone...` indicates that pixels from `SkPngEncoderBase` can be fed | |
| // directly into Rust `png`. | |
| kNone_ExtraRowTransform, | |
| // `kRgba8ToRgb8...` indicates that `SkPngEncoderBase` gives RGBx (8-bit) | |
| // pixels to `onEncodeRow`. And since Rust `png` can't ignore the | |
| // alpha channel (`libpng` can do this via `png_set_filler`), we need to | |
| // do an extra RGBA => RGB transformation before feeding the data into | |
| // Rust. | |
| kRgba8ToRgb8_ExtraRowTransform, | |
| // `kRgba16leToRgba16be...` indicates that `SkPngEncoderBase` gives RGBA (16-bit) | |
| // little endian pixels to `onEncodeRow`. And since Rust `png` can't swap the | |
| // endianess (`libpng` can do this via `png_set_swap`), we need to | |
| // do an extra LE => BE transformation before feeding the data into | |
| // Rust. | |
| kRgba16leToRgba16be_ExtraRowTransform, | |
| // `kRgba16leToRgb16be...` indicates that `SkPngEncoderBase` gives RGBA (16-bit) | |
| // little endian pixels to `onEncodeRow`. And we must ignore alpha + swap endianess. | |
| kRgba16leToRgb16be_ExtraRowTransform, | |
| }; | |
| static std::unique_ptr<SkEncoder> Make(SkWStream*, | |
| const SkPixmap&, | |
| const SkPngRustEncoder::Options& options); | |
| // `public` to support `std::make_unique<SkPngRustEncoderImpl>(...)`. | |
| SkPngRustEncoderImpl(TargetInfo targetInfo, | |
| const SkPixmap& src, | |
| rust::Box<rust_png::StreamWriter> streamWriter, | |
| ExtraRowTransform extraRowTransform); | |
| ~SkPngRustEncoderImpl() override; | |
| protected: | |
| bool onEncodeRow(SkSpan<const uint8_t> row) override; | |
| bool onFinishEncoding() override; | |
| private: | |
| rust::Box<rust_png::StreamWriter> fStreamWriter; | |
| ExtraRowTransform fExtraRowTransform; | |
| std::vector<uint8_t> fExtraRowBuffer; | |
| }; | |
| #endif // SkPngRustEncoderImpl_DEFINED |