Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add png chunk reader, expose more of codec and bitmap #88

Open
wants to merge 13 commits into
base: xamarin-mobile-bindings
Choose a base branch
from
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);
}

mattleibow marked this conversation as resolved.
Show resolved Hide resolved
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);
}