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
4 changes: 4 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -3088,12 +3088,16 @@ skiasharp_build("SkiaSharp") {
]

sources = [
// placed here to help seperate in PR
mgood7123 marked this conversation as resolved.
Show resolved Hide resolved
"src/xamarin/sk_managed_png_chunk_reader.cpp",
mgood7123 marked this conversation as resolved.
Show resolved Hide resolved
"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",
// placed here to help seperate in PR
"src/xamarin/SkManaged_Png_Chunk_Reader.cpp",
"src/xamarin/SkCompatPaint.cpp",
"src/xamarin/SkManagedDrawable.cpp",
"src/xamarin/SkManagedStream.cpp",
Expand Down
7 changes: 7 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,12 @@ 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_read_pixels_imageinfo(sk_bitmap_t* cbitmap, const sk_imageinfo_t* dstInfo, void* dstPixels, size_t rowBytes, int x, int y);
SK_C_API bool sk_bitmap_read_pixels_at_location(sk_bitmap_t* cbitmap, const sk_pixmap_t* cpixmap, int x, int y);
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
5 changes: 3 additions & 2 deletions include/c/sk_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ SK_C_PLUS_PLUS_BEGIN_GUARD

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(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(sk_data_t* data, sk_png_chunk_reader_t* chunk_reader);
mattleibow marked this conversation as resolved.
Show resolved Hide resolved
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);
SK_C_API void sk_codec_get_dimensions(sk_codec_t* codec, sk_isize_t* dimensions);
SK_C_API void sk_codec_get_scaled_dimensions(sk_codec_t* codec, float desiredScale, sk_isize_t* dimensions);
SK_C_API bool sk_codec_get_valid_subset(sk_codec_t* codec, sk_irect_t* desiredSubset);
SK_C_API sk_encoded_image_format_t sk_codec_get_encoded_format(sk_codec_t* codec);
Expand Down
10 changes: 10 additions & 0 deletions include/c/sk_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ typedef struct sk_string_t sk_string_t;
*/
typedef struct sk_bitmap_t sk_bitmap_t;
typedef struct sk_pixmap_t sk_pixmap_t;
// placed here to help seperate in PR
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 +474,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;
mgood7123 marked this conversation as resolved.
Show resolved Hide resolved

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
29 changes: 29 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,18 @@ void sk_bitmap_get_pixel_colors(sk_bitmap_t* cbitmap, sk_color_t* colors) {
}
}

bool sk_bitmap_read_pixels_imageinfo(sk_bitmap_t* cbitmap, const sk_imageinfo_t* dstInfo, void* dstPixels, size_t rowBytes, int x, int y) {
return AsBitmap(cbitmap)->readPixels(AsImageInfo(dstInfo), dstPixels, rowBytes, x, y);
}

bool sk_bitmap_read_pixels_at_location(sk_bitmap_t* cbitmap, const sk_pixmap_t* cpixmap, int x, int y) {
return AsBitmap(cbitmap)->readPixels(*AsPixmap(cpixmap), x, y);
}
mattleibow marked this conversation as resolved.
Show resolved Hide resolved

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
12 changes: 8 additions & 4 deletions src/c/sk_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ size_t sk_codec_min_buffered_bytes_needed(void) {
return SkCodec::MinBufferedBytesNeeded();
}

sk_codec_t* sk_codec_new_from_stream(sk_stream_t* stream, sk_codec_result_t* result) {
sk_codec_t* sk_codec_new_from_stream(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).release());
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(sk_data_t* data) {
return ToCodec(SkCodec::MakeFromData(sk_ref_sp(AsData(data))).release());
sk_codec_t* sk_codec_new_from_data(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) {
Expand All @@ -42,6 +42,10 @@ void sk_codec_get_scaled_dimensions(sk_codec_t* codec, float desiredScale, sk_is
*dimensions = ToISize(AsCodec(codec)->getScaledDimensions(desiredScale));
}

void sk_codec_get_dimensions(sk_codec_t* codec, sk_isize_t* dimensions) {
*dimensions = ToISize(AsCodec(codec)->dimensions());
}

mgood7123 marked this conversation as resolved.
Show resolved Hide resolved
bool sk_codec_get_valid_subset(sk_codec_t* codec, sk_irect_t* desiredSubset) {
return AsCodec(codec)->getValidSubset(AsIRect(desiredSubset));
}
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
29 changes: 29 additions & 0 deletions src/xamarin/SkManaged_Png_Chunk_Reader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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) {
fProcs.fDestroy(this, fContext);
}
mgood7123 marked this conversation as resolved.
Show resolved Hide resolved
}

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,8 @@
// Xamarin
#include "include/xamarin/sk_managedstream.h"
#include "include/xamarin/sk_manageddrawable.h"
// placed here to help seperate in PR
#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 +70,8 @@ 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_colorfilter_unref,
(void*)sk_colorspace_unref,
(void*)sk_colortable_unref,
Expand Down Expand Up @@ -108,6 +112,8 @@ void** KeepSkiaCSymbols (void)
(void*)sk_compatpaint_new,
(void*)sk_managedstream_new,
(void*)sk_manageddrawable_new,
// placed here to help seperate in pr
(void*)sk_managed_png_chunk_reader_new,
(void*)sk_managedtracememorydump_new,
};
return ret;
Expand Down
49 changes: 49 additions & 0 deletions src/xamarin/sk_managed_png_chunk_reader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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) {
gProcs.fDestroy(ToManaged_Png_Chunk_Reader(d), context);
}
mgood7123 marked this conversation as resolved.
Show resolved Hide resolved
}

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);
}