From 3fda7b5b74a42b2b015bebe2031fccff631fb409 Mon Sep 17 00:00:00 2001 From: Nikita Prokopov Date: Fri, 5 Mar 2021 23:38:59 +0100 Subject: [PATCH] Bitmap.makeFromImage, Image.makeRaster, .makeFromBitmap, .getImageInfo, .readPixels (closes #72, #95, #98) --- examples/scenes/images/IMG_7098.jpeg | Bin 0 -> 87480 bytes examples/scenes/src/BitmapImageScene.java | 125 ++++++++++ examples/scenes/src/ColorFiltersScene.java | 8 +- examples/scenes/src/Scene.java | 7 + examples/scenes/src/Scenes.java | 3 +- examples/scenes/src/TextBlobScene.java | 10 +- native/src/Bitmap.cc | 8 +- native/src/Image.cc | 47 +++- native/src/interop.cc | 9 + native/src/interop.hh | 2 + .../main/java/org/jetbrains/skija/Bitmap.java | 137 ++++------- .../org/jetbrains/skija/HasImageInfo.java | 100 ++++++++ .../main/java/org/jetbrains/skija/Image.java | 215 +++++++++++++++--- 13 files changed, 529 insertions(+), 142 deletions(-) create mode 100644 examples/scenes/images/IMG_7098.jpeg create mode 100644 examples/scenes/src/BitmapImageScene.java create mode 100644 shared/src/main/java/org/jetbrains/skija/HasImageInfo.java diff --git a/examples/scenes/images/IMG_7098.jpeg b/examples/scenes/images/IMG_7098.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..098c92c63d2e4c2c9598b92355bc528b5700a1f3 GIT binary patch literal 87480 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%0AhE|{x#R0u65l3;YQYlz+OoKU~#KQ^ne@ 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 literal 0 HcmV?d00001 diff --git a/examples/scenes/src/BitmapImageScene.java b/examples/scenes/src/BitmapImageScene.java new file mode 100644 index 00000000..e74cd284 --- /dev/null +++ b/examples/scenes/src/BitmapImageScene.java @@ -0,0 +1,125 @@ +package org.jetbrains.skija.examples.scenes; + +import java.io.*; +import java.nio.*; +import java.nio.file.*; +import java.nio.file.Path; +import java.util.*; +import java.util.function.*; +import org.jetbrains.skija.*; + +public class BitmapImageScene extends Scene { + public final Image image; + public int x, y; + + public BitmapImageScene() { + try { + image = Image.makeFromEncoded(Files.readAllBytes(Path.of(file("images/IMG_7098.jpeg")))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void advance(Canvas canvas, int width) { + canvas.restore(); + x += 220; + if (x + 220 >= width) { + x = 20; + y += 240; + } + canvas.save(); + canvas.translate(x, y); + } + + @Override + public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int ypos) { + canvas.save(); + canvas.translate(20, 20); + x = 20; + y = 20; + + // Image + canvas.drawImageRect(image, Rect.makeXYWH(0, 0, 200, 200)); + canvas.drawString("Image", 0, 220, inter13, blackFill); + advance(canvas, width); + + // Bitmap + Image.readPixels + var bitmap = new Bitmap(); + bitmap.allocPixels(ImageInfo.makeS32(400, 400, ColorAlphaType.OPAQUE)); + image.readPixels(bitmap); + canvas.drawBitmapRect(bitmap, Rect.makeXYWH(0, 0, 200, 200)); + canvas.drawString("Image.readPixels", 0, 220, inter13, blackFill); + advance(canvas, width); + + // Bitmap + Image.readPixels(50, 50) + var partialBitmap = new Bitmap(); + partialBitmap.allocPixels(new ImageInfo(300, 300, ColorType.GRAY_8, ColorAlphaType.OPAQUE)); + image.readPixels(partialBitmap, 50, 50); + canvas.drawBitmapRect(partialBitmap, Rect.makeXYWH(25, 25, 150, 150)); + canvas.drawString("Image.readPixels(50, 50)", 0, 220, inter13, blackFill); + advance(canvas, width); + + // Bitmap.makeFromImage + var bitmapFromImage = Bitmap.makeFromImage(image); + canvas.drawBitmapRect(bitmapFromImage, Rect.makeXYWH(0, 0, 200, 200)); + canvas.drawString("Bitmap.makeFromImage", 0, 220, inter13, blackFill); + advance(canvas, width); + + // Image.makeFromBitmap + var imageFromBitmap = Image.makeFromBitmap(bitmap); + canvas.drawImageRect(imageFromBitmap, Rect.makeXYWH(0, 0, 200, 200)); + canvas.drawString("Image.makeFromBitmap", 0, 220, inter13, blackFill); + advance(canvas, width); + + // Bitmap readPixels/installPixels + var info = bitmapFromImage.getImageInfo(); + var threshold = 100 + phase() * 100; + byte[] pixels = bitmapFromImage.readPixels(); + ByteBuffer buffer = ByteBuffer.wrap(pixels); // Assume RGBA_8888 + Function luminocity = color -> Color.getR(color) + Color.getG(color) + Color.getB(color); + Comparator cmp = (a, b) -> Integer.compare(luminocity.apply(a), luminocity.apply(b)); + for (int x = 0; x < info.getWidth(); ++x) { + // read pixels + Integer column[] = new Integer[info.getHeight()]; + for (int y = 0; y < info.getHeight(); ++y) + column[y] = buffer.getInt((y * info.getWidth() + x) * info.getBytesPerPixel()); + + // sort pixels + var lastIdx = 0; + for (int y = 0; y < info.getHeight() - 1; ++y) { + if (Math.abs(luminocity.apply(column[y]) - luminocity.apply(column[y + 1])) > threshold) { + Arrays.parallelSort(column, lastIdx, y, cmp); + lastIdx = y; + } + } + Arrays.parallelSort(column, lastIdx, info.getHeight(), cmp); + + // write pixels + for (int y = 0; y < info.getHeight(); ++y) + buffer.putInt((y * info.getWidth() + x) * info.getBytesPerPixel(), column[y]); + } + bitmapFromImage.installPixels(pixels); + canvas.drawBitmapRect(bitmapFromImage, Rect.makeXYWH(0, 0, 200, 200)); + canvas.drawString("Bitmap.readPixels/installPixels", 0, 220, inter13, blackFill); + advance(canvas, width); + + // Image.makeRaster + var imageFromPixels = Image.makeRaster(info, pixels, info.getMinRowBytes()); + canvas.drawImageRect(imageFromPixels, Rect.makeXYWH(0, 0, 200, 200)); + canvas.drawString("Image.makeRaster", 0, 220, inter13, blackFill); + advance(canvas, width); + + // Image.makeRaster + Data + var imageFromData = Image.makeRaster(info, Data.makeFromBytes(pixels), info.getMinRowBytes()); + canvas.drawImageRect(imageFromPixels, Rect.makeXYWH(0, 0, 200, 200)); + canvas.drawString("Image.makeRaster + Data", 0, 220, inter13, blackFill); + advance(canvas, width); + + bitmap.close(); + partialBitmap.close(); + bitmapFromImage.close(); + imageFromBitmap.close(); + imageFromPixels.close(); + imageFromData.close(); + } +} \ No newline at end of file diff --git a/examples/scenes/src/ColorFiltersScene.java b/examples/scenes/src/ColorFiltersScene.java index c1759572..fbe382f9 100644 --- a/examples/scenes/src/ColorFiltersScene.java +++ b/examples/scenes/src/ColorFiltersScene.java @@ -20,10 +20,6 @@ public ColorFiltersScene() { public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int ypos) { canvas.translate(30, 30); - float percent = Math.abs((System.currentTimeMillis() % 3000) / 10f - 150f) - 25f; - percent = Math.round(Math.max(0f, Math.min(100f, percent))); - float ratio = percent / 100f; - byte[] tablePosterize = new byte[256]; for (int i = 0; i < 256; ++i) tablePosterize[i] = (byte) (i & 0x80); @@ -48,12 +44,12 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int 0, 0, 0, 1, 0 )), ColorFilter.makeHSLAMatrix(new ColorMatrix( - 0, 0, 0, 0, ratio, + 0, 0, 0, 0, phase(), 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 )), - ColorFilter.makeLerp(ColorFilter.makeBlend(0x80CC3333, BlendMode.SRC_OVER), ColorFilter.makeBlend(0x803333CC, BlendMode.SRC_OVER), ratio), + ColorFilter.makeLerp(ColorFilter.makeBlend(0x80CC3333, BlendMode.SRC_OVER), ColorFilter.makeBlend(0x803333CC, BlendMode.SRC_OVER), phase()), ColorFilter.makeLighting(0x80CC3333, 0x803333CC), }, diff --git a/examples/scenes/src/Scene.java b/examples/scenes/src/Scene.java index d3152319..0176012d 100644 --- a/examples/scenes/src/Scene.java +++ b/examples/scenes/src/Scene.java @@ -50,4 +50,11 @@ public static void drawStringLeft(Canvas canvas, String text, Rect outer, Font f outer.getTop() + (outer.getHeight() - innerHeight) / 2f - metrics.getAscent(), font, paint); } + + public static float phase() { + var angle = (System.currentTimeMillis() % 5000) / 5000.0 * Math.PI * 2.0; + var phase = Math.sin(angle) * 1.2; + phase = Math.min(1.0, Math.max(-1.0, phase)); + return (float) (phase + 1) / 2f; + } } \ No newline at end of file diff --git a/examples/scenes/src/Scenes.java b/examples/scenes/src/Scenes.java index b7b9b4c5..7da43504 100644 --- a/examples/scenes/src/Scenes.java +++ b/examples/scenes/src/Scenes.java @@ -6,7 +6,7 @@ public class Scenes { public static TreeMap scenes; - public static String currentScene = "Text Line Decorations"; + public static String currentScene = "Bitmap Image"; public static HUD hud = new HUD(); public static boolean vsync = true; public static boolean stats = true; @@ -14,6 +14,7 @@ public class Scenes { static { scenes = new TreeMap<>(); scenes.put("Bitmap", null); + scenes.put("Bitmap Image", null); scenes.put("Blends", null); scenes.put("Color Filters", null); scenes.put("Decorations Bench", null); diff --git a/examples/scenes/src/TextBlobScene.java b/examples/scenes/src/TextBlobScene.java index 9b7aadad..5bf74bca 100644 --- a/examples/scenes/src/TextBlobScene.java +++ b/examples/scenes/src/TextBlobScene.java @@ -48,7 +48,7 @@ public void drawPos(Canvas canvas) { float distance = 0; Point[] pos = new Point[glyphs.length]; - float offset = System.currentTimeMillis() % 1000 / 1000f * 2 * (float) Math.PI; + float offset = phase() * 2 * (float) Math.PI; for (int i = 0; i < pos.length; ++i) { pos[i] = new Point(distance, (float) Math.sin(distance + offset) * 3); @@ -68,7 +68,6 @@ public void drawRSXform(Canvas canvas) { RSXform[] xforms = new RSXform[glyphs.length]; float radius = 50; - int period = 3000; try (Path path = new Path().addCircle(0, 0, radius); PathMeasure measure = new PathMeasure(path); @@ -76,8 +75,7 @@ public void drawRSXform(Canvas canvas) { Paint stroke = new Paint().setColor(0xff3a86ff).setMode(PaintMode.STROKE).setStrokeWidth(1f);) { float length = measure.getLength(); - float relativeOffset = System.currentTimeMillis() % period / (float) period; - float distance = relativeOffset * length; + float distance = phase() * length; for (int i=0; i < xforms.length; ++i) { float w = widths[i]; @@ -134,9 +132,7 @@ public void drawBuilder(Canvas canvas) { } public void drawBounds(Canvas canvas) { - float percent = Math.abs((System.currentTimeMillis() % 10000) / 33f - 150f) - 25f; - percent = Math.round(Math.max(0f, Math.min(100f, percent))); - float width = 100 + percent * 3; + float width = 100 + phase() * 300; int color = 0xFF454A6F; try (var shaper = Shaper.make(); diff --git a/native/src/Bitmap.cc b/native/src/Bitmap.cc index 6668d00f..577775b0 100644 --- a/native/src/Bitmap.cc +++ b/native/src/Bitmap.cc @@ -35,13 +35,7 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skija_Bitmap__1nSwap extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skija_Bitmap__1nGetImageInfo (JNIEnv* env, jclass jclass, jlong ptr) { SkBitmap* instance = reinterpret_cast(static_cast(ptr)); - const SkImageInfo& info = instance->info(); - return env->NewObject(skija::ImageInfo::cls, skija::ImageInfo::ctor, - info.width(), - info.height(), - static_cast(info.colorType()), - static_cast(info.alphaType()), - reinterpret_cast(info.refColorSpace().release())); + return skija::ImageInfo::toJava(env, instance->info()); } extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skija_Bitmap__1nGetRowBytesAsPixels diff --git a/native/src/Image.cc b/native/src/Image.cc index 38a15730..4fd837c0 100644 --- a/native/src/Image.cc +++ b/native/src/Image.cc @@ -4,6 +4,40 @@ #include "SkImage.h" #include "interop.hh" +extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_Image__1nMakeRaster + (JNIEnv* env, jclass jclass, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jbyteArray bytesArr, jlong rowBytes) { + SkColorSpace* colorSpace = reinterpret_cast(static_cast(colorSpacePtr)); + SkImageInfo imageInfo = SkImageInfo::Make(width, + height, + static_cast(colorType), + static_cast(alphaType), + sk_ref_sp(colorSpace)); + void* bytes = env->GetPrimitiveArrayCritical(bytesArr, 0); + sk_sp image = SkImage::MakeRasterCopy(SkPixmap(imageInfo, bytes, rowBytes)); + env->ReleasePrimitiveArrayCritical(bytesArr, bytes, 0); + return reinterpret_cast(image.release()); +} + +extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_Image__1nMakeRasterData + (JNIEnv* env, jclass jclass, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jlong dataPtr, jlong rowBytes) { + SkColorSpace* colorSpace = reinterpret_cast(static_cast(colorSpacePtr)); + SkImageInfo imageInfo = SkImageInfo::Make(width, + height, + static_cast(colorType), + static_cast(alphaType), + sk_ref_sp(colorSpace)); + SkData* data = reinterpret_cast(static_cast(dataPtr)); + sk_sp image = SkImage::MakeRasterData(imageInfo, sk_ref_sp(data), rowBytes); + return reinterpret_cast(image.release()); +} + +extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_Image__1nMakeFromBitmap + (JNIEnv* env, jclass jclass, jlong bitmapPtr) { + SkBitmap* bitmap = reinterpret_cast(static_cast(bitmapPtr)); + sk_sp image = SkImage::MakeFromBitmap(*bitmap); + return reinterpret_cast(image.release()); +} + extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_Image__1nMakeFromEncoded (JNIEnv* env, jclass jclass, jbyteArray encodedArray) { jsize encodedLen = env->GetArrayLength(encodedArray); @@ -16,10 +50,10 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_Image__1nMakeFromEnc return reinterpret_cast(image.release()); } -extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_Image__1nGetDimensions +extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skija_Image__1nGetImageInfo (JNIEnv* env, jclass jclass, jlong ptr) { SkImage* instance = reinterpret_cast(static_cast(ptr)); - return packTwoInts(instance->width(), instance->height()); + return skija::ImageInfo::toJava(env, instance->imageInfo()); } extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_Image__1nEncodeToData @@ -46,3 +80,12 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_Image__1nMakeShaderC sk_sp shader = instance->makeShader(static_cast(tmx), static_cast(tmy), sampling, localMatrix.get()); return reinterpret_cast(shader.release()); } + +extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skija_Image__1nReadPixelsBitmap + (JNIEnv* env, jclass jclass, jlong ptr, jlong contextPtr, jlong bitmapPtr, jint srcX, jint srcY, jboolean cache) { + SkImage* instance = reinterpret_cast(static_cast(ptr)); + GrDirectContext* context = reinterpret_cast(static_cast(contextPtr)); + SkBitmap* bitmap = reinterpret_cast(static_cast(bitmapPtr)); + auto cachingHint = cache ? SkImage::CachingHint::kAllow_CachingHint : SkImage::CachingHint::kDisallow_CachingHint; + return instance->readPixels(context, bitmap->info(), bitmap->getPixels(), bitmap->pixmap().rowBytes(), srcX, srcY, cachingHint); +} diff --git a/native/src/interop.cc b/native/src/interop.cc index 801502ff..c52f726a 100644 --- a/native/src/interop.cc +++ b/native/src/interop.cc @@ -302,6 +302,15 @@ namespace skija { void onUnload(JNIEnv* env) { env->DeleteGlobalRef(cls); } + + jobject toJava(JNIEnv* env, const SkImageInfo& info) { + return env->NewObject(cls, ctor, + info.width(), + info.height(), + static_cast(info.colorType()), + static_cast(info.alphaType()), + reinterpret_cast(info.refColorSpace().release())); + } } namespace IPoint { diff --git a/native/src/interop.hh b/native/src/interop.hh index 4132aead..e68801d6 100644 --- a/native/src/interop.hh +++ b/native/src/interop.hh @@ -4,6 +4,7 @@ #include #include "SkFontMetrics.h" #include "SkFontStyle.h" +#include "SkImageInfo.h" #include "SkMatrix.h" #include "SkM44.h" #include "SkPaint.h" @@ -138,6 +139,7 @@ namespace skija { extern jmethodID ctor; void onLoad(JNIEnv* env); void onUnload(JNIEnv* env); + jobject toJava(JNIEnv* env, const SkImageInfo& imageInfo); } namespace IPoint { diff --git a/shared/src/main/java/org/jetbrains/skija/Bitmap.java b/shared/src/main/java/org/jetbrains/skija/Bitmap.java index b750da53..30def7f3 100644 --- a/shared/src/main/java/org/jetbrains/skija/Bitmap.java +++ b/shared/src/main/java/org/jetbrains/skija/Bitmap.java @@ -5,8 +5,11 @@ import org.jetbrains.annotations.*; import org.jetbrains.skija.impl.*; -public class Bitmap extends Managed { +public class Bitmap extends Managed implements HasImageInfo { static { Library.staticLoad(); } + + @ApiStatus.Internal + public ImageInfo _imageInfo = null; @ApiStatus.Internal public Bitmap(long ptr) { @@ -45,6 +48,19 @@ public Bitmap makeClone() { } } + @NotNull @Contract("-> new") + public static Bitmap makeFromImage(@NotNull Image image) { + assert image != null : "Can’t makeFromImage with image == null"; + var bitmap = new Bitmap(); + bitmap.allocPixels(image.getImageInfo()); + if (image.readPixels(bitmap)) + return bitmap; + else { + bitmap.close(); + throw new RuntimeException("Failed to readPixels from " + image); + } + } + /** * Swaps the fields of the two bitmaps. * @@ -55,72 +71,24 @@ public Bitmap makeClone() { public void swap(@NotNull Bitmap other) { Stats.onNativeCall(); _nSwap(_ptr, Native.getPtr(other)); + _imageInfo = null; Reference.reachabilityFence(this); Reference.reachabilityFence(other); } - @NotNull + @Override @NotNull public ImageInfo getImageInfo() { try { - Stats.onNativeCall(); - return _nGetImageInfo(_ptr); + if (_imageInfo == null) { + Stats.onNativeCall(); + _imageInfo = _nGetImageInfo(_ptr); + } + return _imageInfo; } finally { Reference.reachabilityFence(this); - } - } - - /** - * Returns pixel count in each row. Should be equal or less than - * getRowBytes() / getImageInfo().getBytesPerPixel(). - * - * May be less than getPixelRef().getWidth(). Will not exceed getPixelRef().getWidth() less - * - * @return pixel width in ImageInfo - */ - public int getWidth() { - return getImageInfo()._width; - } - - /** - * Returns pixel row count. - * - * Maybe be less than getPixelRef().getHeight(). Will not exceed getPixelRef().getHeight() - * - * @return pixel height in ImageInfo - */ - public int getHeight() { - return getImageInfo()._height; - } - - @NotNull - public ColorInfo getColorInfo() { - return getImageInfo()._colorInfo; - } - - @NotNull - public ColorType getColorType() { - return getImageInfo()._colorInfo._colorType; - } - - @NotNull - public ColorAlphaType getAlphaType() { - return getImageInfo()._colorInfo._alphaType; + } } - @Nullable - public ColorSpace getColorSpace() { - return getImageInfo()._colorInfo._colorSpace; - } - - /** - * Returns number of bytes per pixel required by ColorType. - * Returns zero if colorType is {@link ColorType#UNKNOWN}. - * - * @return bytes in pixel - */ - public int getBytesPerPixel() { - return getImageInfo().getBytesPerPixel(); - } /** * Returns number of pixels that fit on row. Should be greater than or equal to @@ -137,28 +105,6 @@ public int getRowBytesAsPixels() { } } - /** - * Returns bit shift converting row bytes to row pixels. - * Returns zero for {@link ColorType#UNKNOWN}. - * - * @return one of: 0, 1, 2, 3; left shift to convert pixels to bytes - */ - public int getShiftPerPixel() { - return getImageInfo().getShiftPerPixel(); - } - - /** - * Returns true if either getWidth() or getHeight() are zero. - * - * Does not check if PixelRef is null; call {@link drawsNothing()} to check - * getWidth(), getHeight(), and PixelRef. - * - * @return true if dimensions do not enclose area - */ - public boolean isEmpty() { - return getImageInfo().isEmpty(); - } - /** * Returns true if PixelRef is null. * @@ -238,6 +184,7 @@ public long getRowBytes() { public boolean setAlphaType(ColorAlphaType alphaType) { try { Stats.onNativeCall(); + _imageInfo = null; return _nSetAlphaType(_ptr, alphaType.ordinal()); } finally { Reference.reachabilityFence(this); @@ -295,20 +242,6 @@ public Bitmap setImmutable() { return this; } - /** - *

Returns true if ColorAlphaType is set to hint that all pixels are opaque; their - * alpha value is implicitly or explicitly 1.0. If true, and all pixels are - * not opaque, Skia may draw incorrectly.

- * - *

Does not check if SkColorType allows alpha, or if any pixel value has - * transparency.

- * - * @return true if ImageInfo ColorAlphaType is {@link ColorAlphaType#OPAQUE} - */ - public boolean isOpaque() { - return getImageInfo()._colorInfo.isOpaque(); - } - /** *

Resets to its initial state; all fields are set to zero, as if Bitmap had * been initialized by Bitmap().

@@ -324,6 +257,7 @@ public boolean isOpaque() { @NotNull @Contract("-> this") public Bitmap reset() { Stats.onNativeCall(); + _imageInfo = null; _nReset(_ptr); return this; } @@ -400,6 +334,7 @@ public IRect getSubset() { * @see
https://fiddle.skia.org/c/@Bitmap_setInfo */ public boolean setImageInfo(@NotNull ImageInfo imageInfo) { + _imageInfo = null; return setImageInfo(imageInfo, 0); } @@ -436,6 +371,7 @@ public boolean setImageInfo(@NotNull ImageInfo imageInfo) { */ public boolean setImageInfo(@NotNull ImageInfo imageInfo, long rowBytes) { try { + _imageInfo = null; Stats.onNativeCall(); return _nSetImageInfo(_ptr, imageInfo._width, @@ -468,6 +404,7 @@ public boolean setImageInfo(@NotNull ImageInfo imageInfo, long rowBytes) { */ public boolean allocPixelsFlags(@NotNull ImageInfo imageInfo, boolean zeroPixels) { try { + _imageInfo = null; Stats.onNativeCall(); return _nAllocPixelsFlags(_ptr, imageInfo._width, @@ -501,6 +438,7 @@ public boolean allocPixelsFlags(@NotNull ImageInfo imageInfo, boolean zeroPixels */ public boolean allocPixels(@NotNull ImageInfo info, long rowBytes) { try { + _imageInfo = null; Stats.onNativeCall(); return _nAllocPixelsRowBytes(_ptr, info._width, @@ -577,6 +515,10 @@ public boolean allocN32Pixels(int width, int height, boolean opaque) { return allocPixels(ImageInfo.makeN32(width, height, opaque ? ColorAlphaType.OPAQUE : ColorAlphaType.PREMUL)); } + public boolean installPixels(byte[] pixels) { + return installPixels(getImageInfo(), pixels, getRowBytes()); + } + /** *

Sets ImageInfo to info following the rules in setImageInfo(), and creates PixelRef * containing pixels and rowBytes.

@@ -593,6 +535,7 @@ public boolean installPixels(@NotNull ImageInfo info, @Nullable byte[] pixels, long rowBytes) { try { + _imageInfo = null; Stats.onNativeCall(); return _nInstallPixels(_ptr, info._width, @@ -618,6 +561,7 @@ public boolean installPixels(@NotNull ImageInfo info, */ public boolean allocPixels() { try { + _imageInfo = null; Stats.onNativeCall(); return _nAllocPixels(_ptr); } finally { @@ -688,6 +632,7 @@ public IPoint getPixelRefOrigin() { @NotNull @Contract("_, _, _ -> this") public Bitmap setPixelRef(@Nullable PixelRef pixelRef, int dx, int dy) { try { + _imageInfo = null; Stats.onNativeCall(); _nSetPixelRef(_ptr, Native.getPtr(pixelRef), dx, dy); return this; @@ -868,6 +813,11 @@ public boolean extractSubset(@NotNull Bitmap dst, @NotNull IRect subset) { } } + @Nullable + public byte[] readPixels() { + return readPixels(getImageInfo(), getRowBytes(), 0, 0); + } + /** *

Copies a rect of pixels from Bitmap. Copy starts at (srcX, srcY), * and does not exceed Bitmap (getWidth(), getHeight()).

@@ -1014,6 +964,7 @@ public static class _FinalizerHolder { @ApiStatus.Internal public static native long _nMake(); @ApiStatus.Internal public static native long _nMakeClone(long ptr); @ApiStatus.Internal public static native void _nSwap(long ptr, long otherPtr); + @ApiStatus.Internal public static native long _nGetPixmap(long ptr); @ApiStatus.Internal public static native ImageInfo _nGetImageInfo(long ptr); @ApiStatus.Internal public static native int _nGetRowBytesAsPixels(long ptr); @ApiStatus.Internal public static native boolean _nIsNull(long ptr); diff --git a/shared/src/main/java/org/jetbrains/skija/HasImageInfo.java b/shared/src/main/java/org/jetbrains/skija/HasImageInfo.java new file mode 100644 index 00000000..6ad6a36a --- /dev/null +++ b/shared/src/main/java/org/jetbrains/skija/HasImageInfo.java @@ -0,0 +1,100 @@ +package org.jetbrains.skija; + +import java.lang.ref.*; +import lombok.*; +import org.jetbrains.annotations.*; +import org.jetbrains.skija.impl.*; + +public interface HasImageInfo { + ImageInfo getImageInfo(); + + /** + * Returns pixel count in each row. Should be equal or less than + * getRowBytes() / getImageInfo().getBytesPerPixel(). + * + * May be less than getPixelRef().getWidth(). Will not exceed getPixelRef().getWidth() less + * + * @return pixel width in ImageInfo + */ + default int getWidth() { + return getImageInfo()._width; + } + + /** + * Returns pixel row count. + * + * Maybe be less than getPixelRef().getHeight(). Will not exceed getPixelRef().getHeight() + * + * @return pixel height in ImageInfo + */ + default int getHeight() { + return getImageInfo()._height; + } + + @NotNull + default ColorInfo getColorInfo() { + return getImageInfo()._colorInfo; + } + + @NotNull + default ColorType getColorType() { + return getImageInfo()._colorInfo._colorType; + } + + @NotNull + default ColorAlphaType getAlphaType() { + return getImageInfo()._colorInfo._alphaType; + } + + @Nullable + default ColorSpace getColorSpace() { + return getImageInfo()._colorInfo._colorSpace; + } + + /** + * Returns number of bytes per pixel required by ColorType. + * Returns zero if colorType is {@link ColorType#UNKNOWN}. + * + * @return bytes in pixel + */ + default int getBytesPerPixel() { + return getImageInfo().getBytesPerPixel(); + } + + + /** + * Returns bit shift converting row bytes to row pixels. + * Returns zero for {@link ColorType#UNKNOWN}. + * + * @return one of: 0, 1, 2, 3; left shift to convert pixels to bytes + */ + default int getShiftPerPixel() { + return getImageInfo().getShiftPerPixel(); + } + + /** + * Returns true if either getWidth() or getHeight() are zero. + * + * Does not check if PixelRef is null; call {@link Bitmap#drawsNothing()} to check + * getWidth(), getHeight(), and PixelRef. + * + * @return true if dimensions do not enclose area + */ + default boolean isEmpty() { + return getImageInfo().isEmpty(); + } + + /** + *

Returns true if ColorAlphaType is set to hint that all pixels are opaque; their + * alpha value is implicitly or explicitly 1.0. If true, and all pixels are + * not opaque, Skia may draw incorrectly.

+ * + *

Does not check if SkColorType allows alpha, or if any pixel value has + * transparency.

+ * + * @return true if ImageInfo ColorAlphaType is {@link ColorAlphaType#OPAQUE} + */ + default boolean isOpaque() { + return getImageInfo()._colorInfo.isOpaque(); + } +} diff --git a/shared/src/main/java/org/jetbrains/skija/Image.java b/shared/src/main/java/org/jetbrains/skija/Image.java index 411397c8..b9915306 100644 --- a/shared/src/main/java/org/jetbrains/skija/Image.java +++ b/shared/src/main/java/org/jetbrains/skija/Image.java @@ -4,25 +4,149 @@ import org.jetbrains.annotations.*; import org.jetbrains.skija.impl.*; -public class Image extends RefCnt { +public class Image extends RefCnt implements HasImageInfo { static { Library.staticLoad(); } - @ApiStatus.Internal public int _width = -1; - @ApiStatus.Internal public int _height = -1; + @ApiStatus.Internal + public ImageInfo _imageInfo = null; + + @ApiStatus.Internal + public Image(long ptr) { + super(ptr); + } + + /** + *

Creates Image from pixels.

+ * + *

Image is returned if pixels are valid. Valid Pixmap parameters include:

+ *
    + *
  • dimensions are greater than zero;
  • + *
  • each dimension fits in 29 bits;
  • + *
  • ColorType and AlphaType are valid, and ColorType is not ColorType.UNKNOWN;
  • + *
  • row bytes are large enough to hold one row of pixels;
  • + *
  • pixel address is not null.
  • + *
+ * + * @param imageInfo ImageInfo + * @param bytes pixels array + * @param rowBytes how many bytes in a row + * @return Image + * + * @see https://fiddle.skia.org/c/@Image_MakeRasterCopy + */ + public static Image makeRaster(ImageInfo imageInfo, byte[] bytes, long rowBytes) { + try { + Stats.onNativeCall(); + long ptr = _nMakeRaster(imageInfo._width, + imageInfo._height, + imageInfo._colorInfo._colorType.ordinal(), + imageInfo._colorInfo._alphaType.ordinal(), + Native.getPtr(imageInfo._colorInfo._colorSpace), + bytes, + rowBytes); + if (ptr == 0) + throw new RuntimeException("Failed to makeRaster " + imageInfo + " " + bytes + " " + rowBytes); + return new Image(ptr); + } finally { + Reference.reachabilityFence(imageInfo._colorInfo._colorSpace); + } + } + + /** + *

Creates Image from pixels.

+ * + *

Image is returned if pixels are valid. Valid Pixmap parameters include:

+ *
    + *
  • dimensions are greater than zero;
  • + *
  • each dimension fits in 29 bits;
  • + *
  • ColorType and AlphaType are valid, and ColorType is not ColorType.UNKNOWN;
  • + *
  • row bytes are large enough to hold one row of pixels;
  • + *
  • pixel address is not null.
  • + *
+ * + * @param imageInfo ImageInfo + * @param data pixels array + * @param rowBytes how many bytes in a row + * @return Image + */ + public static Image makeRaster(ImageInfo imageInfo, Data data, long rowBytes) { + try { + Stats.onNativeCall(); + long ptr = _nMakeRasterData(imageInfo._width, + imageInfo._height, + imageInfo._colorInfo._colorType.ordinal(), + imageInfo._colorInfo._alphaType.ordinal(), + Native.getPtr(imageInfo._colorInfo._colorSpace), + Native.getPtr(data), + rowBytes); + if (ptr == 0) + throw new RuntimeException("Failed to makeRaster " + imageInfo + " " + data + " " + rowBytes); + return new Image(ptr); + } finally { + Reference.reachabilityFence(imageInfo._colorInfo._colorSpace); + Reference.reachabilityFence(data); + } + } + + /** + *

Creates Image from bitmap, sharing or copying bitmap pixels. If the bitmap + * is marked immutable, and its pixel memory is shareable, it may be shared + * instead of copied.

+ * + *

Image is returned if bitmap is valid. Valid Bitmap parameters include:

+ *
    + *
  • dimensions are greater than zero;
  • + *
  • each dimension fits in 29 bits;
  • + *
  • ColorType and AlphaType are valid, and ColorType is not ColorType.UNKNOWN;
  • + *
  • row bytes are large enough to hold one row of pixels;
  • + *
  • pixel address is not nullptr.
  • + *
+ * + * @param bitmap ImageInfo, row bytes, and pixels + * @return created Image + * + * @see https://fiddle.skia.org/c/@Image_MakeFromBitmap + */ + @NotNull @Contract("_ -> new") + public static Image makeFromBitmap(@NotNull Bitmap bitmap) { + try { + assert bitmap != null : "Can’t makeFromBitmap with bitmap == null"; + Stats.onNativeCall(); + long ptr = _nMakeFromBitmap(Native.getPtr(bitmap)); + if (ptr == 0) + throw new RuntimeException("Failed to Image::makeFromBitmap " + bitmap); + return new Image(ptr); + } finally { + Reference.reachabilityFence(bitmap); + } + } public static Image makeFromEncoded(byte[] bytes) { Stats.onNativeCall(); return new Image(_nMakeFromEncoded(bytes)); } - public int getWidth() { - if (_width == -1) _getDimensions(); - return _width; - } - - public int getHeight() { - if (_height == -1) _getDimensions(); - return _height; + /** + * Returns a ImageInfo describing the width, height, color type, alpha type, and color space + * of the Image. + * + * @return image info of Image. + */ + @Override @NotNull + public ImageInfo getImageInfo() { + try { + if (_imageInfo == null) { + synchronized(this) { + if (_imageInfo == null) { + Stats.onNativeCall(); + _imageInfo = _nGetImageInfo(_ptr); + } + } + } + return _imageInfo; + } finally { + Reference.reachabilityFence(this); + } } /** @@ -74,17 +198,6 @@ public Data encodeToData(EncodedImageFormat format, int quality) { } } - public void _getDimensions() { - try { - Stats.onNativeCall(); - long res = _nGetDimensions(_ptr); - _height = (int) (res & 0xFFFFFFFF); - _width = (int) (res >>> 32); - } finally { - Reference.reachabilityFence(this); - } - } - @NotNull public Shader makeShader() { return makeShader(FilterTileMode.CLAMP, FilterTileMode.CLAMP, SamplingMode.DEFAULT, null); @@ -138,14 +251,64 @@ public Shader makeShader(@NotNull FilterTileMode tmx, } } - @ApiStatus.Internal - public Image(long ptr) { - super(ptr); + public boolean readPixels(@NotNull Bitmap dst) { + return readPixels(null, dst, 0, 0, false); + } + + public boolean readPixels(@NotNull Bitmap dst, int srcX, int srcY) { + return readPixels(null, dst, srcX, srcY, false); + } + + /** + *

Copies Rect of pixels from Image to Bitmap. Copy starts at offset (srcX, srcY), + * and does not exceed Image (getWidth(), getHeight()).

+ * + *

dst specifies width, height, ColorType, AlphaType, and ColorSpace of destination.

+ * + *

Returns true if pixels are copied. Returns false if:

+ *
    + *
  • dst has no pixels allocated.
  • + *
+ * + *

Pixels are copied only if pixel conversion is possible. If Image ColorType is + * ColorType.GRAY_8, or ColorType.ALPHA_8; dst.getColorType() must match. + * If Image ColorType is ColorType.GRAY_8, dst.getColorSpace() must match. + * If Image AlphaType is AlphaType.OPAQUE, dst.getAlphaType() must + * match. If Image ColorSpace is null, dst.getColorSpace() must match. Returns + * false if pixel conversion is not possible.

+ * + *

srcX and srcY may be negative to copy only top or left of source. Returns + * false if getWidth() or getHeight() is zero or negative.

+ * + *

Returns false if abs(srcX) >= Image.getWidth(), or if abs(srcY) >= Image.getHeight().

+ * + *

If cache is true, pixels may be retained locally, otherwise pixels are not added to the local cache.

+ * + * @param context the DirectContext in play, if it exists + * @param dst destination bitmap + * @param srcX column index whose absolute value is less than getWidth() + * @param srcY row index whose absolute value is less than getHeight() + * @param cache whether the pixels should be cached locally + * @return true if pixels are copied to dstPixels + */ + public boolean readPixels(@Nullable DirectContext context, @NotNull Bitmap dst, int srcX, int srcY, boolean cache) { + try { + assert dst != null : "Can’t readPixels with dst == null"; + return _nReadPixelsBitmap(_ptr, Native.getPtr(context), Native.getPtr(dst), srcX, srcY, cache); + } finally { + Reference.reachabilityFence(this); + Reference.reachabilityFence(context); + Reference.reachabilityFence(dst); + } } + @ApiStatus.Internal public static native long _nMakeRaster(int width, int height, int colorType, int alphaType, long colorSpacePtr, byte[] pixels, long rowBytes); + @ApiStatus.Internal public static native long _nMakeRasterData(int width, int height, int colorType, int alphaType, long colorSpacePtr, long dataPtr, long rowBytes); + @ApiStatus.Internal public static native long _nMakeFromBitmap(long bitmapPtr); @ApiStatus.Internal public static native long _nMakeFromEncoded(byte[] bytes); - @ApiStatus.Internal public static native long _nGetDimensions(long ptr); + @ApiStatus.Internal public static native ImageInfo _nGetImageInfo(long ptr); @ApiStatus.Internal public static native long _nEncodeToData(long ptr, int format, int quality); @ApiStatus.Internal public static native long _nMakeShader(long ptr, int tmx, int tmy, int filterMode, int mipmapMode, float[] localMatrix); @ApiStatus.Internal public static native long _nMakeShaderCubic(long ptr, int tmx, int tmy, float B, float C, float[] localMatrix); + @ApiStatus.Internal public static native boolean _nReadPixelsBitmap(long ptr, long contextPtr, long bitmapPtr, int srcX, int srcY, boolean cache); } \ No newline at end of file