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_managed_png_chunk_reader.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/SkManaged_Png_Chunk_Reader.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_png_chunk_reader_and_selection_policy(sk_stream_t* stream, sk_codec_result_t* result, sk_png_chunk_reader_t* chunk_reader, sk_codec_selection_policy_t policy);
SK_C_API sk_codec_t* sk_codec_new_from_data_with_png_chunk_reader(sk_data_t* data, sk_png_chunk_reader_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_png_chunk_reader_t sk_png_chunk_reader_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 @@ -472,6 +473,14 @@ typedef enum {
HEIF_SK_ENCODED_FORMAT,
} sk_encoded_image_format_t;

/**
* Enum describing selection policy.
*/
typedef enum {
kPreferStillImage,
kPreferAnimation,
} 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
47 changes: 47 additions & 0 deletions include/xamarin/SkManaged_Png_Chunk_Reader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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 SkManaged_Png_Chunk_Reader_h
#define SkManaged_Png_Chunk_Reader_h

#include "include/core/SkPngChunkReader.h"
#include "include/core/SkTypes.h"

class SK_API SkManaged_Png_Chunk_Reader;

// delegate declarations

// managed _Png_Chunk_Reader
class SkManaged_Png_Chunk_Reader : public SkPngChunkReader {
public:
SkManaged_Png_Chunk_Reader(void* context);

~SkManaged_Png_Chunk_Reader() override;

public:
typedef bool (*ReadChunkProc) (SkManaged_Png_Chunk_Reader* d, void* context, const char* tag, const void* data, size_t length);
typedef void (*DestroyProc) (SkManaged_Png_Chunk_Reader* 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_managed_png_chunk_reader.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_managed_png_chunk_reader_DEFINED
#define sk_managed_png_chunk_reader_DEFINED

#include "sk_xamarin.h"

#include "include/c/sk_types.h"

SK_C_PLUS_PLUS_BEGIN_GUARD

typedef struct sk_managed_png_chunk_reader_t sk_managed_png_chunk_reader_t;

typedef bool (*sk_managed_png_chunk_reader_read_chunk_proc) (sk_managed_png_chunk_reader_t* d, void* context, const char tag[], const void* data, size_t length);
typedef void (*sk_managed_png_chunk_reader_destroy_proc) (sk_managed_png_chunk_reader_t* d, void* context);

typedef struct {
sk_managed_png_chunk_reader_read_chunk_proc fReadChunk;
sk_managed_png_chunk_reader_destroy_proc fDestroy;
} sk_managed_png_chunk_reader_procs_t;

SK_X_API sk_managed_png_chunk_reader_t* sk_managed_png_chunk_reader_new(void* context);
SK_X_API void sk_managed_png_chunk_reader_delete(sk_managed_png_chunk_reader_t*);
SK_X_API void sk_managed_png_chunk_reader_set_procs(sk_managed_png_chunk_reader_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_png_chunk_reader_and_selection_policy(sk_stream_t* stream, sk_codec_result_t* result, sk_png_chunk_reader_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_png_chunk_reader(sk_data_t* data, sk_png_chunk_reader_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
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_png_chunk_reader_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/SkManaged_Png_Chunk_Reader.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/SkManaged_Png_Chunk_Reader.h"

SkManaged_Png_Chunk_Reader::Procs SkManaged_Png_Chunk_Reader::fProcs;

void SkManaged_Png_Chunk_Reader::setProcs(SkManaged_Png_Chunk_Reader::Procs procs) {
fProcs = procs;
}

SkManaged_Png_Chunk_Reader::SkManaged_Png_Chunk_Reader(void* context) {
fContext = context;
}

SkManaged_Png_Chunk_Reader::~SkManaged_Png_Chunk_Reader() {
if (!fProcs.fDestroy) return;
fProcs.fDestroy(this, fContext);
}

bool SkManaged_Png_Chunk_Reader::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_managed_png_chunk_reader.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_png_chunk_reader_and_selection_policy,
(void*)sk_codec_new_from_data_with_png_chunk_reader,
(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_managed_png_chunk_reader_new,
(void*)sk_managedtracememorydump_new,
};
return ret;
Expand Down
48 changes: 48 additions & 0 deletions src/xamarin/sk_managed_png_chunk_reader.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/SkManaged_Png_Chunk_Reader.h"

#include "include/xamarin/sk_managed_png_chunk_reader.h"
#include "src/c/sk_types_priv.h"

static inline SkManaged_Png_Chunk_Reader* AsManaged_Png_Chunk_Reader(sk_managed_png_chunk_reader_t* d) {
return reinterpret_cast<SkManaged_Png_Chunk_Reader*>(d);
}
static inline sk_managed_png_chunk_reader_t* ToManaged_Png_Chunk_Reader(SkManaged_Png_Chunk_Reader* d) {
return reinterpret_cast<sk_managed_png_chunk_reader_t*>(d);
}

static sk_managed_png_chunk_reader_procs_t gProcs;

bool readChunk(SkManaged_Png_Chunk_Reader* d, void* context, const char tag[], const void* data, size_t length) {
if (!gProcs.fReadChunk) return false;
return gProcs.fReadChunk(ToManaged_Png_Chunk_Reader(d), context, tag, data, length);
}

void destroy(SkManaged_Png_Chunk_Reader* d, void* context) {
if (!gProcs.fDestroy) return;
gProcs.fDestroy(ToManaged_Png_Chunk_Reader(d), context);
}

sk_managed_png_chunk_reader_t* sk_managed_png_chunk_reader_new(void* context) {
return ToManaged_Png_Chunk_Reader(new SkManaged_Png_Chunk_Reader(context));
}

void sk_managed_png_chunk_reader_delete(sk_managed_png_chunk_reader_t* d) {
delete AsManaged_Png_Chunk_Reader(d);
}

void sk_managed_png_chunk_reader_set_procs(sk_managed_png_chunk_reader_procs_t procs) {
gProcs = procs;

SkManaged_Png_Chunk_Reader::Procs p;
p.fReadChunk = readChunk;
p.fDestroy = destroy;

SkManaged_Png_Chunk_Reader::setProcs(p);
}