Skip to content

Commit

Permalink
Fix encodeToData() bug (#1882)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Thibault Malbranche <[email protected]>
  • Loading branch information
wcandillon and Titozzz authored Sep 28, 2023
1 parent 273beb5 commit 56cf8eb
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 23 deletions.
38 changes: 15 additions & 23 deletions package/cpp/api/JsiSkImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,32 @@ class JsiSkImage : public JsiSkWrappingSkPtrHostObject<SkImage> {
std::make_shared<JsiSkShader>(getContext(), std::move(shader)));
}

JSI_HOST_FUNCTION(encodeToBytes) {
sk_sp<SkData> encodeImageData(const jsi::Value *arguments, size_t count) {
// Get optional parameters
auto format =
count >= 1 ? static_cast<SkEncodedImageFormat>(arguments[0].asNumber())
: SkEncodedImageFormat::kPNG;
auto quality = count == 2 ? arguments[1].asNumber() : 100.0;

// Get data
auto quality = count == 2 ? arguments[1].asNumber() : 100.0;
auto image = getObject();
if (image->isTextureBacked()) {
image = image->makeNonTextureImage();
}
sk_sp<SkData> data;
if (format == SkEncodedImageFormat::kJPEG) {
SkJpegEncoder::Options options;
options.fQuality = quality;
data = SkJpegEncoder::Encode(nullptr, getObject().get(), options);
data = SkJpegEncoder::Encode(nullptr, image.get(), options);
} else {
SkPngEncoder::Options options;
data = SkPngEncoder::Encode(nullptr, getObject().get(), options);
data = SkPngEncoder::Encode(nullptr, image.get(), options);
}
return data;
}

JSI_HOST_FUNCTION(encodeToBytes) {
auto data = encodeImageData(arguments, count);

auto arrayCtor =
runtime.global().getPropertyAsFunction(runtime, "Uint8Array");
size_t size = data->size();
Expand All @@ -99,25 +108,8 @@ class JsiSkImage : public JsiSkWrappingSkPtrHostObject<SkImage> {
}

JSI_HOST_FUNCTION(encodeToBase64) {
// Get optional parameters
auto format =
count >= 1 ? static_cast<SkEncodedImageFormat>(arguments[0].asNumber())
: SkEncodedImageFormat::kPNG;
auto data = encodeImageData(arguments, count);

auto quality = count == 2 ? arguments[1].asNumber() : 100.0;
auto image = getObject();
if (image->isTextureBacked()) {
image = image->makeNonTextureImage();
}
sk_sp<SkData> data;
if (format == SkEncodedImageFormat::kJPEG) {
SkJpegEncoder::Options options;
options.fQuality = quality;
data = SkJpegEncoder::Encode(nullptr, image.get(), options);
} else {
SkPngEncoder::Options options;
data = SkPngEncoder::Encode(nullptr, image.get(), options);
}
auto len = SkBase64::Encode(data->bytes(), data->size(), nullptr);
auto buffer = std::string(len, 0);
SkBase64::Encode(data->bytes(), data->size(),
Expand Down
75 changes: 75 additions & 0 deletions package/src/renderer/__tests__/e2e/DataEncoding.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { importSkia, surface } from "../setup";

describe("Data Encoding", () => {
it("encodeToBytes() from CPU image", async () => {
const result = await surface.eval((Skia) => {
const data = Skia.Data.fromBase64(
"R0lGODlhAQABAIAAAGGqHwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="
);
const img = Skia.Image.MakeImageFromEncoded(data);
if (!img) {
return [];
}
return Array.from(img.encodeToBytes());
});
const { Skia } = importSkia();
const data = Skia.Data.fromBase64(
"R0lGODlhAQABAIAAAGGqHwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="
);
const img = Skia.Image.MakeImageFromEncoded(data)!;
expect(img).toBeTruthy();
expect(result).toEqual(Array.from(img.encodeToBytes()));
});
it("encodeToBase64() from CPU image", async () => {
const result = await surface.eval((Skia) => {
const data = Skia.Data.fromBase64(
"R0lGODlhAQABAIAAAGGqHwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="
);
const img = Skia.Image.MakeImageFromEncoded(data);
if (!img) {
return "";
}
return img.encodeToBase64();
});
const { Skia } = importSkia();

const data = Skia.Data.fromBase64(
"R0lGODlhAQABAIAAAGGqHwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="
);
const img = Skia.Image.MakeImageFromEncoded(data)!;
expect(img).toBeTruthy();
expect(result).toEqual(img.encodeToBase64());
});
it("encodeToBytes() from GPU image", async () => {
const result = await surface.eval((Skia) => {
const data = Skia.Data.fromBase64(
"R0lGODlhAQABAIAAAGGqHwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="
);
const img = Skia.Image.MakeImageFromEncoded(data);
if (!img) {
return [];
}
const offscreen = Skia.Surface.MakeOffscreen(1, 1)!;
const canvas = offscreen.getCanvas();
canvas.drawImage(img, 0, 0);
return Array.from(offscreen.makeImageSnapshot().encodeToBytes());
});
expect(result.length).toBeGreaterThan(0);
});
it("encodeToBase64() from GPU image", async () => {
const result = await surface.eval((Skia) => {
const data = Skia.Data.fromBase64(
"R0lGODlhAQABAIAAAGGqHwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="
);
const img = Skia.Image.MakeImageFromEncoded(data);
if (!img) {
return "";
}
const offscreen = Skia.Surface.MakeOffscreen(1, 1)!;
const canvas = offscreen.getCanvas();
canvas.drawImage(img, 0, 0);
return offscreen.makeImageSnapshot().encodeToBase64();
});
expect(result.length).toBeGreaterThan(0);
});
});

0 comments on commit 56cf8eb

Please sign in to comment.