Skip to content
Open
2 changes: 2 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions include/c/sk_bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions include/c/sk_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions include/c/sk_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
46 changes: 46 additions & 0 deletions include/xamarin/SkManagedPngChunkReader.h
Original file line number Diff line number Diff line change
@@ -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
33 changes: 33 additions & 0 deletions include/xamarin/sk_managedpngchunkreader.h
Original file line number Diff line number Diff line change
@@ -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
21 changes: 21 additions & 0 deletions src/c/sk_bitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
}
Expand Down Expand Up @@ -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();
Expand All @@ -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);
}
Expand Down
9 changes: 9 additions & 0 deletions src/c/sk_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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> 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);
}
Expand Down
4 changes: 4 additions & 0 deletions src/c/sk_enums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
1 change: 1 addition & 0 deletions src/c/sk_types_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
28 changes: 28 additions & 0 deletions src/xamarin/SkManagedPngChunkReader.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
6 changes: 6 additions & 0 deletions src/xamarin/SkiaKeeper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand Down
48 changes: 48 additions & 0 deletions src/xamarin/sk_managedpngchunkreader.cpp
Original file line number Diff line number Diff line change
@@ -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<SkManagedPngChunkReader*>(d);
}
static inline sk_managedpngchunkreader_t* ToManagedPngChunkReader(SkManagedPngChunkReader* d) {
return reinterpret_cast<sk_managedpngchunkreader_t*>(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);
}