diff --git a/BUILD.gn b/BUILD.gn index 61facb7a1957..6f28508971ef 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -3088,12 +3088,14 @@ skiasharp_build("SkiaSharp") { ] sources = [ + "src/xamarin/sk_managedpngchunkreader.cpp", "src/xamarin/sk_compatpaint.cpp", "src/xamarin/sk_manageddrawable.cpp", "src/xamarin/sk_managedstream.cpp", "src/xamarin/sk_managedtracememorydump.cpp", "src/xamarin/sk_xamarin.cpp", "src/xamarin/SkiaKeeper.c", + "src/xamarin/SkManagedPngChunkReader.cpp", "src/xamarin/SkCompatPaint.cpp", "src/xamarin/SkManagedDrawable.cpp", "src/xamarin/SkManagedStream.cpp", diff --git a/include/c/sk_bitmap.h b/include/c/sk_bitmap.h index bf019a05e8ad..752bd25babf5 100644 --- a/include/c/sk_bitmap.h +++ b/include/c/sk_bitmap.h @@ -17,9 +17,11 @@ SK_C_PLUS_PLUS_BEGIN_GUARD SK_C_API void sk_bitmap_destructor(sk_bitmap_t* cbitmap); SK_C_API sk_bitmap_t* sk_bitmap_new(void); SK_C_API void sk_bitmap_get_info(sk_bitmap_t* cbitmap, sk_imageinfo_t* info); +SK_C_API bool sk_bitmap_set_info(sk_bitmap_t* cbitmap, const sk_imageinfo_t* requestedInfo, size_t rowBytes); SK_C_API void* sk_bitmap_get_pixels(sk_bitmap_t* cbitmap, size_t* length); SK_C_API size_t sk_bitmap_get_row_bytes(sk_bitmap_t* cbitmap); SK_C_API size_t sk_bitmap_get_byte_count(sk_bitmap_t* cbitmap); +SK_C_API uint32_t sk_bitmap_get_generation_id(sk_bitmap_t* cbitmap); SK_C_API void sk_bitmap_reset(sk_bitmap_t* cbitmap); SK_C_API bool sk_bitmap_is_null(sk_bitmap_t* cbitmap); SK_C_API bool sk_bitmap_is_immutable(sk_bitmap_t* cbitmap); @@ -32,7 +34,10 @@ SK_C_API uint32_t* sk_bitmap_get_addr_32(sk_bitmap_t* cbitmap, int x, int y); SK_C_API void* sk_bitmap_get_addr(sk_bitmap_t* cbitmap, int x, int y); SK_C_API sk_color_t sk_bitmap_get_pixel_color(sk_bitmap_t* cbitmap, int x, int y); SK_C_API bool sk_bitmap_ready_to_draw(sk_bitmap_t* cbitmap); +SK_C_API bool sk_bitmap_compute_is_opaque(sk_bitmap_t* cbitmap); +SK_C_API const sk_pixmap_t* sk_bitmap_get_pixmap(sk_bitmap_t* cbitmap); SK_C_API void sk_bitmap_get_pixel_colors(sk_bitmap_t* cbitmap, sk_color_t* colors); +SK_C_API bool sk_bitmap_write_pixels_at_location(sk_bitmap_t* cbitmap, const sk_pixmap_t* cpixmap, int x, int y); SK_C_API bool sk_bitmap_install_pixels(sk_bitmap_t* cbitmap, const sk_imageinfo_t* cinfo, void* pixels, size_t rowBytes, const sk_bitmap_release_proc releaseProc, void* context); SK_C_API bool sk_bitmap_install_pixels_with_pixmap(sk_bitmap_t* cbitmap, const sk_pixmap_t* cpixmap); SK_C_API bool sk_bitmap_install_mask_pixels(sk_bitmap_t* cbitmap, const sk_mask_t* cmask); diff --git a/include/c/sk_codec.h b/include/c/sk_codec.h index 75201447b3b8..d1fb4bfa65c3 100644 --- a/include/c/sk_codec.h +++ b/include/c/sk_codec.h @@ -18,6 +18,8 @@ SK_C_API size_t sk_codec_min_buffered_bytes_needed(void); SK_C_API sk_codec_t* sk_codec_new_from_stream(sk_stream_t* stream, sk_codec_result_t* result); SK_C_API sk_codec_t* sk_codec_new_from_data(sk_data_t* data); +SK_C_API sk_codec_t* sk_codec_new_from_stream_with_pngchunkreader_and_selection_policy(sk_stream_t* stream, sk_codec_result_t* result, sk_pngchunkreader_t* chunk_reader, sk_codec_selection_policy_t policy); +SK_C_API sk_codec_t* sk_codec_new_from_data_with_pngchunkreader(sk_data_t* data, sk_pngchunkreader_t* chunk_reader); SK_C_API void sk_codec_destroy(sk_codec_t* codec); SK_C_API void sk_codec_get_info(sk_codec_t* codec, sk_imageinfo_t* info); SK_C_API sk_encodedorigin_t sk_codec_get_origin(sk_codec_t* codec); diff --git a/include/c/sk_types.h b/include/c/sk_types.h index 6a97f91e9d51..866a03614f64 100644 --- a/include/c/sk_types.h +++ b/include/c/sk_types.h @@ -344,6 +344,7 @@ typedef struct sk_string_t sk_string_t; */ typedef struct sk_bitmap_t sk_bitmap_t; typedef struct sk_pixmap_t sk_pixmap_t; +typedef struct sk_pngchunkreader_t sk_pngchunkreader_t; typedef struct sk_colorfilter_t sk_colorfilter_t; typedef struct sk_imagefilter_t sk_imagefilter_t; typedef struct sk_imagefilter_croprect_t sk_imagefilter_croprect_t; @@ -473,6 +474,14 @@ typedef enum { AVIF_SK_ENCODED_FORMAT, } sk_encoded_image_format_t; +/** + * Enum describing selection policy. + */ +typedef enum { + PREFER_STILL_IMAGE_SK_CODEC_SELECTION_POLICY, + PREFER_ANIMATION_SK_CODEC_SELECTION_POLICY, +} sk_codec_selection_policy_t; + typedef enum { TOP_LEFT_SK_ENCODED_ORIGIN = 1, // Default TOP_RIGHT_SK_ENCODED_ORIGIN = 2, // Reflected across y-axis diff --git a/include/xamarin/SkManagedPngChunkReader.h b/include/xamarin/SkManagedPngChunkReader.h new file mode 100644 index 000000000000..b3b3d8804e9a --- /dev/null +++ b/include/xamarin/SkManagedPngChunkReader.h @@ -0,0 +1,46 @@ +/* + * Copyright 2022 Microsoft Corporation. All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkManagedPngChunkReader_h +#define SkManagedPngChunkReader_h + +#include "include/core/SkPngChunkReader.h" +#include "include/core/SkTypes.h" + +class SK_API SkManagedPngChunkReader; + +// delegate declarations + +class SkManagedPngChunkReader : public SkPngChunkReader { +public: + SkManagedPngChunkReader(void* context); + + ~SkManagedPngChunkReader() override; + +public: + typedef bool (*ReadChunkProc) (SkManagedPngChunkReader* d, void* context, const char* tag, const void* data, size_t length); + typedef void (*DestroyProc) (SkManagedPngChunkReader* d, void* context); + + struct Procs { + ReadChunkProc fReadChunk = nullptr; + DestroyProc fDestroy = nullptr; + }; + + static void setProcs(Procs procs); + +protected: + bool readChunk(const char tag[], const void* data, size_t length) override; + +private: + void* fContext; + static Procs fProcs; + + typedef SkPngChunkReader INHERITED; +}; + + +#endif diff --git a/include/xamarin/sk_managedpngchunkreader.h b/include/xamarin/sk_managedpngchunkreader.h new file mode 100644 index 000000000000..851891754817 --- /dev/null +++ b/include/xamarin/sk_managedpngchunkreader.h @@ -0,0 +1,33 @@ +/* + * Copyright 2022 Microsoft Corporation. All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef sk_managedpngchunkreader_DEFINED +#define sk_managedpngchunkreader_DEFINED + +#include "sk_xamarin.h" + +#include "include/c/sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +typedef struct sk_managedpngchunkreader_t sk_managedpngchunkreader_t; + +typedef bool (*sk_managedpngchunkreader_read_chunk_proc) (sk_managedpngchunkreader_t* d, void* context, const char tag[], const void* data, size_t length); +typedef void (*sk_managedpngchunkreader_destroy_proc) (sk_managedpngchunkreader_t* d, void* context); + +typedef struct { + sk_managedpngchunkreader_read_chunk_proc fReadChunk; + sk_managedpngchunkreader_destroy_proc fDestroy; +} sk_managedpngchunkreader_procs_t; + +SK_X_API sk_managedpngchunkreader_t* sk_managedpngchunkreader_new(void* context); +SK_X_API void sk_managedpngchunkreader_delete(sk_managedpngchunkreader_t*); +SK_X_API void sk_managedpngchunkreader_set_procs(sk_managedpngchunkreader_procs_t procs); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/src/c/sk_bitmap.cpp b/src/c/sk_bitmap.cpp index 7e6d84270a4f..4d301921235b 100644 --- a/src/c/sk_bitmap.cpp +++ b/src/c/sk_bitmap.cpp @@ -31,6 +31,10 @@ void sk_bitmap_get_info(sk_bitmap_t* cbitmap, sk_imageinfo_t* info) { *info = ToImageInfo(AsBitmap(cbitmap)->info()); } +bool sk_bitmap_set_info(sk_bitmap_t* cbitmap, const sk_imageinfo_t* requestedInfo, size_t rowBytes) { + return AsBitmap(cbitmap)->setInfo(AsImageInfo(requestedInfo), rowBytes); +} + void* sk_bitmap_get_pixels(sk_bitmap_t* cbitmap, size_t* length) { SkBitmap* bmp = AsBitmap(cbitmap); *length = bmp->computeByteSize(); @@ -45,6 +49,10 @@ size_t sk_bitmap_get_byte_count(sk_bitmap_t* cbitmap) { return AsBitmap(cbitmap)->computeByteSize(); } +uint32_t sk_bitmap_get_generation_id(sk_bitmap_t* cbitmap) { + return AsBitmap(cbitmap)->getGenerationID(); +} + void sk_bitmap_reset(sk_bitmap_t* cbitmap) { AsBitmap(cbitmap)->reset(); } @@ -93,6 +101,15 @@ bool sk_bitmap_ready_to_draw(sk_bitmap_t* cbitmap) { return AsBitmap(cbitmap)->readyToDraw(); } +bool sk_bitmap_compute_is_opaque(sk_bitmap_t* cbitmap) { + return SkBitmap::ComputeIsOpaque(*AsBitmap(cbitmap)); +} + +const sk_pixmap_t* sk_bitmap_get_pixmap(sk_bitmap_t* cbitmap) { + const SkPixmap& pixmap = AsBitmap(cbitmap)->pixmap(); + return ToPixmap(&pixmap); +} + void sk_bitmap_get_pixel_colors(sk_bitmap_t* cbitmap, sk_color_t* colors) { SkBitmap* bmp = AsBitmap(cbitmap); int w = bmp->width(); @@ -105,6 +122,10 @@ void sk_bitmap_get_pixel_colors(sk_bitmap_t* cbitmap, sk_color_t* colors) { } } +bool sk_bitmap_write_pixels_at_location(sk_bitmap_t* cbitmap, const sk_pixmap_t* cpixmap, int x, int y) { + return AsBitmap(cbitmap)->writePixels(*AsPixmap(cpixmap), x, y); +} + bool sk_bitmap_install_pixels(sk_bitmap_t* cbitmap, const sk_imageinfo_t* cinfo, void* pixels, size_t rowBytes, const sk_bitmap_release_proc releaseProc, void* context) { return AsBitmap(cbitmap)->installPixels(AsImageInfo(cinfo), pixels, rowBytes, releaseProc, context); } diff --git a/src/c/sk_codec.cpp b/src/c/sk_codec.cpp index d2bb62f7f867..f8d4f849760d 100644 --- a/src/c/sk_codec.cpp +++ b/src/c/sk_codec.cpp @@ -26,6 +26,15 @@ sk_codec_t* sk_codec_new_from_data(sk_data_t* data) { return ToCodec(SkCodec::MakeFromData(sk_ref_sp(AsData(data))).release()); } +sk_codec_t* sk_codec_new_from_stream_with_pngchunkreader_and_selection_policy(sk_stream_t* stream, sk_codec_result_t* result, sk_pngchunkreader_t* chunk_reader, sk_codec_selection_policy_t policy) { + std::unique_ptr skstream(AsStream(stream)); + return ToCodec(SkCodec::MakeFromStream(std::move(skstream), (SkCodec::Result*)result, AsPngChunkReader(chunk_reader), (SkCodec::SelectionPolicy)policy).release()); +} + +sk_codec_t* sk_codec_new_from_data_with_pngchunkreader(sk_data_t* data, sk_pngchunkreader_t* chunk_reader) { + return ToCodec(SkCodec::MakeFromData(sk_ref_sp(AsData(data)), AsPngChunkReader(chunk_reader)).release()); +} + void sk_codec_destroy(sk_codec_t* codec) { delete AsCodec(codec); } diff --git a/src/c/sk_enums.cpp b/src/c/sk_enums.cpp index dc2b3edac3bb..748a8d594f6c 100644 --- a/src/c/sk_enums.cpp +++ b/src/c/sk_enums.cpp @@ -250,6 +250,10 @@ static_assert ((int)SkCodec::ZeroInitialized::kNo_ZeroInitialized == (int)NO_ static_assert ((int)SkCodec::SkScanlineOrder::kTopDown_SkScanlineOrder == (int)TOP_DOWN_SK_CODEC_SCANLINE_ORDER, ASSERT_MSG(SkCodec::SkScanlineOrder, sk_codec_scanline_order_t)); static_assert ((int)SkCodec::SkScanlineOrder::kBottomUp_SkScanlineOrder == (int)BOTTOM_UP_SK_CODEC_SCANLINE_ORDER, ASSERT_MSG(SkCodec::SkScanlineOrder, sk_codec_scanline_order_t)); +// sk_codec_selection_policy_t +static_assert ((int)SkCodec::SelectionPolicy::kPreferStillImage == (int)PREFER_STILL_IMAGE_SK_CODEC_SELECTION_POLICY, ASSERT_MSG(SkCodec::SelectionPolicy, sk_codec_selection_policy_t)); +static_assert ((int)SkCodec::SelectionPolicy::kPreferAnimation == (int)PREFER_ANIMATION_SK_CODEC_SELECTION_POLICY, ASSERT_MSG(SkCodec::SelectionPolicy, sk_codec_selection_policy_t)); + // sk_codecanimation_disposalmethod_t static_assert ((int)SkCodecAnimation::DisposalMethod::kKeep == (int)KEEP_SK_CODEC_ANIMATION_DISPOSAL_METHOD, ASSERT_MSG(SkCodec::SkScanlineOrder, sk_codecanimation_disposalmethod_t)); static_assert ((int)SkCodecAnimation::DisposalMethod::kRestoreBGColor == (int)RESTORE_BG_COLOR_SK_CODEC_ANIMATION_DISPOSAL_METHOD, ASSERT_MSG(SkCodec::SkScanlineOrder, sk_codecanimation_disposalmethod_t)); diff --git a/src/c/sk_types_priv.h b/src/c/sk_types_priv.h index af460d8994d0..8eb58f667a86 100644 --- a/src/c/sk_types_priv.h +++ b/src/c/sk_types_priv.h @@ -127,6 +127,7 @@ DEF_CLASS_MAP(SkPathMeasure, sk_pathmeasure_t, PathMeasure) DEF_CLASS_MAP(SkPicture, sk_picture_t, Picture) DEF_CLASS_MAP(SkPictureRecorder, sk_picture_recorder_t, PictureRecorder) DEF_CLASS_MAP(SkPixmap, sk_pixmap_t, Pixmap) +DEF_CLASS_MAP(SkPngChunkReader, sk_pngchunkreader_t, PngChunkReader) DEF_CLASS_MAP(SkRegion, sk_region_t, Region) DEF_CLASS_MAP(SkRRect, sk_rrect_t, RRect) DEF_CLASS_MAP(SkRuntimeEffect, sk_runtimeeffect_t, RuntimeEffect) diff --git a/src/xamarin/SkManagedPngChunkReader.cpp b/src/xamarin/SkManagedPngChunkReader.cpp new file mode 100644 index 000000000000..b319b22070a7 --- /dev/null +++ b/src/xamarin/SkManagedPngChunkReader.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2022 Microsoft Corporation. All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/xamarin/SkManagedPngChunkReader.h" + +SkManagedPngChunkReader::Procs SkManagedPngChunkReader::fProcs; + +void SkManagedPngChunkReader::setProcs(SkManagedPngChunkReader::Procs procs) { + fProcs = procs; +} + +SkManagedPngChunkReader::SkManagedPngChunkReader(void* context) { + fContext = context; +} + +SkManagedPngChunkReader::~SkManagedPngChunkReader() { + if (!fProcs.fDestroy) return; + fProcs.fDestroy(this, fContext); +} + +bool SkManagedPngChunkReader::readChunk(const char tag[], const void* data, size_t length) { + if (!fProcs.fReadChunk) return false; + return fProcs.fReadChunk(this, fContext, tag, data, length); +} diff --git a/src/xamarin/SkiaKeeper.c b/src/xamarin/SkiaKeeper.c index 67f482881e68..6c34702d2c0f 100644 --- a/src/xamarin/SkiaKeeper.c +++ b/src/xamarin/SkiaKeeper.c @@ -53,6 +53,7 @@ // Xamarin #include "include/xamarin/sk_managedstream.h" #include "include/xamarin/sk_manageddrawable.h" +#include "include/xamarin/sk_managedpngchunkreader.h" #include "include/xamarin/sk_managedtracememorydump.h" #include "include/xamarin/sk_compatpaint.h" @@ -68,6 +69,10 @@ void** KeepSkiaCSymbols (void) (void*)sk_bitmap_new, (void*)sk_canvas_destroy, (void*)sk_codec_min_buffered_bytes_needed, + (void*)sk_codec_new_from_data, + (void*)sk_codec_new_from_stream, + (void*)sk_codec_new_from_stream_with_pngchunkreader_and_selection_policy, + (void*)sk_codec_new_from_data_with_pngchunkreader, (void*)sk_colorfilter_unref, (void*)sk_colorspace_unref, (void*)sk_colortable_unref, @@ -108,6 +113,7 @@ void** KeepSkiaCSymbols (void) (void*)sk_compatpaint_new, (void*)sk_managedstream_new, (void*)sk_manageddrawable_new, + (void*)sk_managedpngchunkreader_new, (void*)sk_managedtracememorydump_new, }; return ret; diff --git a/src/xamarin/sk_managedpngchunkreader.cpp b/src/xamarin/sk_managedpngchunkreader.cpp new file mode 100644 index 000000000000..41abfee87f3c --- /dev/null +++ b/src/xamarin/sk_managedpngchunkreader.cpp @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Microsoft Corporation. All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/xamarin/SkManagedPngChunkReader.h" + +#include "include/xamarin/sk_managedpngchunkreader.h" +#include "src/c/sk_types_priv.h" + +static inline SkManagedPngChunkReader* AsManagedPngChunkReader(sk_managedpngchunkreader_t* d) { + return reinterpret_cast(d); +} +static inline sk_managedpngchunkreader_t* ToManagedPngChunkReader(SkManagedPngChunkReader* d) { + return reinterpret_cast(d); +} + +static sk_managedpngchunkreader_procs_t gProcs; + +bool readChunk(SkManagedPngChunkReader* d, void* context, const char tag[], const void* data, size_t length) { + if (!gProcs.fReadChunk) return false; + return gProcs.fReadChunk(ToManagedPngChunkReader(d), context, tag, data, length); +} + +void destroy(SkManagedPngChunkReader* d, void* context) { + if (!gProcs.fDestroy) return; + gProcs.fDestroy(ToManagedPngChunkReader(d), context); +} + +sk_managedpngchunkreader_t* sk_managedpngchunkreader_new(void* context) { + return ToManagedPngChunkReader(new SkManagedPngChunkReader(context)); +} + +void sk_managedpngchunkreader_delete(sk_managedpngchunkreader_t* d) { + delete AsManagedPngChunkReader(d); +} + +void sk_managedpngchunkreader_set_procs(sk_managedpngchunkreader_procs_t procs) { + gProcs = procs; + + SkManagedPngChunkReader::Procs p; + p.fReadChunk = readChunk; + p.fDestroy = destroy; + + SkManagedPngChunkReader::setProcs(p); +}