Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1abf5d62 authored by Chris Craik's avatar Chris Craik
Browse files

Add inPremutiplied option to BitmapFactory.Options, functionality in Bitmap

bug:2248948

Change-Id: I8fdd649332667598504a1076d5a447572bd53086
parent b4f6a01d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -8831,6 +8831,7 @@ package android.graphics {
    method public void setHeight(int);
    method public void setPixel(int, int, int);
    method public void setPixels(int[], int, int, int, int, int, int);
    method public final void setPremultiplied(boolean);
    method public void setWidth(int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
@@ -8880,6 +8881,7 @@ package android.graphics {
    field public boolean inMutable;
    field public boolean inPreferQualityOverSpeed;
    field public android.graphics.Bitmap.Config inPreferredConfig;
    field public boolean inPremultiplied;
    field public boolean inPurgeable;
    field public int inSampleSize;
    field public boolean inScaled;
+7 −7
Original line number Diff line number Diff line
@@ -776,7 +776,7 @@ class GLES20Canvas extends HardwareCanvas {
    @Override
    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
        Bitmap bitmap = patch.getBitmap();
        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
        throwIfCannotDraw(bitmap);
        // Shaders are ignored when drawing patches
        int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
        try {
@@ -791,7 +791,7 @@ class GLES20Canvas extends HardwareCanvas {
    @Override
    public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
        Bitmap bitmap = patch.getBitmap();
        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
        throwIfCannotDraw(bitmap);
        // Shaders are ignored when drawing patches
        int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
        try {
@@ -808,7 +808,7 @@ class GLES20Canvas extends HardwareCanvas {

    @Override
    public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
        throwIfCannotDraw(bitmap);
        // Shaders are ignored when drawing bitmaps
        int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
        try {
@@ -824,7 +824,7 @@ class GLES20Canvas extends HardwareCanvas {

    @Override
    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
        throwIfCannotDraw(bitmap);
        // Shaders are ignored when drawing bitmaps
        int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
        try {
@@ -841,7 +841,7 @@ class GLES20Canvas extends HardwareCanvas {

    @Override
    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
        throwIfCannotDraw(bitmap);
        // Shaders are ignored when drawing bitmaps
        int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
        try {
@@ -868,7 +868,7 @@ class GLES20Canvas extends HardwareCanvas {

    @Override
    public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
        throwIfCannotDraw(bitmap);
        // Shaders are ignored when drawing bitmaps
        int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
        try {
@@ -944,7 +944,7 @@ class GLES20Canvas extends HardwareCanvas {
    @Override
    public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
            int vertOffset, int[] colors, int colorOffset, Paint paint) {
        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
        throwIfCannotDraw(bitmap);
        if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) {
            throw new ArrayIndexOutOfBoundsException();
        }
+116 −45
Original line number Diff line number Diff line
@@ -38,6 +38,23 @@ static void FromColor_D32(void* dst, const SkColor src[], int width,
    }
}

static void FromColor_D32_Raw(void* dst, const SkColor src[], int width,
                          int, int) {
    // SkColor's ordering may be different from SkPMColor
    if (SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER) {
        memcpy(dst, src, width * sizeof(SkColor));
        return;
    }

    // order isn't same, repack each pixel manually
    SkPMColor* d = (SkPMColor*)dst;
    for (int i = 0; i < width; i++) {
        SkColor c = *src++;
        *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),
                                   SkColorGetG(c), SkColorGetB(c));
    }
}

static void FromColor_D565(void* dst, const SkColor src[], int width,
                           int x, int y) {
    uint16_t* d = (uint16_t*)dst;
@@ -56,19 +73,35 @@ static void FromColor_D4444(void* dst, const SkColor src[], int width,

    DITHER_4444_SCAN(y);
    for (int stop = x + width; x < stop; x++) {
        SkPMColor c = SkPreMultiplyColor(*src++);
        *d++ = SkDitherARGB32To4444(c, DITHER_VALUE(x));
//        *d++ = SkPixel32ToPixel4444(c);
        SkPMColor pmc = SkPreMultiplyColor(*src++);
        *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x));
//        *d++ = SkPixel32ToPixel4444(pmc);
    }
}

static void FromColor_D4444_Raw(void* dst, const SkColor src[], int width,
                            int x, int y) {
    SkPMColor16* d = (SkPMColor16*)dst;

    DITHER_4444_SCAN(y);
    for (int stop = x + width; x < stop; x++) {
        SkColor c = *src++;

        // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied
        SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),
                                            SkColorGetG(c), SkColorGetB(c));
        *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x));
//        *d++ = SkPixel32ToPixel4444(pmc);
    }
}

// can return NULL
static FromColorProc ChooseFromColorProc(SkBitmap::Config config) {
static FromColorProc ChooseFromColorProc(SkBitmap::Config config, bool isPremultiplied) {
    switch (config) {
        case SkBitmap::kARGB_8888_Config:
            return FromColor_D32;
            return isPremultiplied ? FromColor_D32 : FromColor_D32_Raw;
        case SkBitmap::kARGB_4444_Config:
            return FromColor_D4444;
            return isPremultiplied ? FromColor_D4444 : FromColor_D4444_Raw;
        case SkBitmap::kRGB_565_Config:
            return FromColor_D565;
        default:
@@ -77,13 +110,12 @@ static FromColorProc ChooseFromColorProc(SkBitmap::Config config) {
    return NULL;
}

bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors,
                            int srcOffset, int srcStride,
bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride,
        int x, int y, int width, int height,
                            const SkBitmap& dstBitmap) {
        const SkBitmap& dstBitmap, bool isPremultiplied) {
    SkAutoLockPixels alp(dstBitmap);
    void* dst = dstBitmap.getPixels();
    FromColorProc proc = ChooseFromColorProc(dstBitmap.config());
    FromColorProc proc = ChooseFromColorProc(dstBitmap.config(), isPremultiplied);

    if (NULL == dst || NULL == proc) {
        return false;
@@ -122,6 +154,17 @@ static void ToColor_S32_Alpha(SkColor dst[], const void* src, int width,
    } while (--width != 0);
}

static void ToColor_S32_Raw(SkColor dst[], const void* src, int width,
                              SkColorTable*) {
    SkASSERT(width > 0);
    const SkPMColor* s = (const SkPMColor*)src;
    do {
        SkPMColor c = *s++;
        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
                                SkGetPackedG32(c), SkGetPackedB32(c));
    } while (--width != 0);
}

static void ToColor_S32_Opaque(SkColor dst[], const void* src, int width,
                               SkColorTable*) {
    SkASSERT(width > 0);
@@ -142,6 +185,17 @@ static void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width,
    } while (--width != 0);
}

static void ToColor_S4444_Raw(SkColor dst[], const void* src, int width,
                                SkColorTable*) {
    SkASSERT(width > 0);
    const SkPMColor16* s = (const SkPMColor16*)src;
    do {
        SkPMColor c = SkPixel4444ToPixel32(*s++);
        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
                                SkGetPackedG32(c), SkGetPackedB32(c));
    } while (--width != 0);
}

static void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width,
                                 SkColorTable*) {
    SkASSERT(width > 0);
@@ -175,6 +229,19 @@ static void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width,
    ctable->unlockColors(false);
}

static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
                              SkColorTable* ctable) {
    SkASSERT(width > 0);
    const uint8_t* s = (const uint8_t*)src;
    const SkPMColor* colors = ctable->lockColors();
    do {
        SkPMColor c = colors[*s++];
        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
                                SkGetPackedG32(c), SkGetPackedB32(c));
    } while (--width != 0);
    ctable->unlockColors(false);
}

static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
                               SkColorTable* ctable) {
    SkASSERT(width > 0);
@@ -189,19 +256,22 @@ static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
}

// can return NULL
static ToColorProc ChooseToColorProc(const SkBitmap& src) {
static ToColorProc ChooseToColorProc(const SkBitmap& src, bool isPremultiplied) {
    switch (src.config()) {
        case SkBitmap::kARGB_8888_Config:
            return src.isOpaque() ? ToColor_S32_Opaque : ToColor_S32_Alpha;
            if (src.isOpaque()) return ToColor_S32_Opaque;
            return isPremultiplied ? ToColor_S32_Alpha : ToColor_S32_Raw;
        case SkBitmap::kARGB_4444_Config:
            return src.isOpaque() ? ToColor_S4444_Opaque : ToColor_S4444_Alpha;
            if (src.isOpaque()) return ToColor_S4444_Opaque;
            return isPremultiplied ? ToColor_S4444_Alpha : ToColor_S4444_Raw;
        case SkBitmap::kRGB_565_Config:
            return ToColor_S565;
        case SkBitmap::kIndex8_Config:
            if (src.getColorTable() == NULL) {
                return NULL;
            }
            return src.isOpaque() ? ToColor_SI8_Opaque : ToColor_SI8_Alpha;
            if (src.isOpaque()) return ToColor_SI8_Opaque;
            return isPremultiplied ? ToColor_SI8_Raw : ToColor_SI8_Alpha;
        default:
            break;
    }
@@ -211,6 +281,12 @@ static ToColorProc ChooseToColorProc(const SkBitmap& src) {
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

static int getPremulBitmapCreateFlags(bool isMutable) {
    int flags = GraphicsJNI::kBitmapCreateFlag_Premultiplied;
    if (isMutable) flags |= GraphicsJNI::kBitmapCreateFlag_Mutable;
    return flags;
}

static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
                              int offset, int stride, int width, int height,
                              SkBitmap::Config config, jboolean isMutable) {
@@ -236,10 +312,12 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
    }

    if (jColors != NULL) {
        GraphicsJNI::SetPixels(env, jColors, offset, stride, 0, 0, width, height, bitmap);
        GraphicsJNI::SetPixels(env, jColors, offset, stride,
                0, 0, width, height, bitmap, true);
    }

    return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff, isMutable, NULL, NULL);
    return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff,
            getPremulBitmapCreateFlags(isMutable), NULL, NULL);
}

static jobject Bitmap_copy(JNIEnv* env, jobject, const SkBitmap* src,
@@ -250,8 +328,8 @@ static jobject Bitmap_copy(JNIEnv* env, jobject, const SkBitmap* src,
    if (!src->copyTo(&result, dstConfig, &allocator)) {
        return NULL;
    }

    return GraphicsJNI::createBitmap(env, new SkBitmap(result), allocator.getStorageObj(), isMutable, NULL, NULL);
    return GraphicsJNI::createBitmap(env, new SkBitmap(result), allocator.getStorageObj(),
            getPremulBitmapCreateFlags(isMutable), NULL, NULL);
}

static void Bitmap_destructor(JNIEnv* env, jobject, SkBitmap* bitmap) {
@@ -347,14 +425,6 @@ static void Bitmap_erase(JNIEnv* env, jobject, SkBitmap* bitmap, jint color) {
    bitmap->eraseColor(color);
}

static int Bitmap_width(JNIEnv* env, jobject, SkBitmap* bitmap) {
    return bitmap->width();
}

static int Bitmap_height(JNIEnv* env, jobject, SkBitmap* bitmap) {
    return bitmap->height();
}

static int Bitmap_rowBytes(JNIEnv* env, jobject, SkBitmap* bitmap) {
    return bitmap->rowBytes();
}
@@ -449,7 +519,9 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
    bitmap->unlockPixels();

    blob.release();
    return GraphicsJNI::createBitmap(env, bitmap, buffer, isMutable, NULL, NULL, density);

    return GraphicsJNI::createBitmap(env, bitmap, buffer, getPremulBitmapCreateFlags(isMutable),
            NULL, NULL, density);
}

static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
@@ -527,16 +599,17 @@ static jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz,
        env->ReleaseIntArrayElements(offsetXY, array, 0);
    }

    return GraphicsJNI::createBitmap(env, dst, allocator.getStorageObj(), true, NULL, NULL);
    return GraphicsJNI::createBitmap(env, dst, allocator.getStorageObj(),
            GraphicsJNI::kBitmapCreateFlag_Mutable, NULL, NULL);
}

///////////////////////////////////////////////////////////////////////////////

static int Bitmap_getPixel(JNIEnv* env, jobject, const SkBitmap* bitmap,
                           int x, int y) {
        int x, int y, bool isPremultiplied) {
    SkAutoLockPixels alp(*bitmap);

    ToColorProc proc = ChooseToColorProc(*bitmap);
    ToColorProc proc = ChooseToColorProc(*bitmap, isPremultiplied);
    if (NULL == proc) {
        return 0;
    }
@@ -552,10 +625,10 @@ static int Bitmap_getPixel(JNIEnv* env, jobject, const SkBitmap* bitmap,

static void Bitmap_getPixels(JNIEnv* env, jobject, const SkBitmap* bitmap,
        jintArray pixelArray, int offset, int stride,
                             int x, int y, int width, int height) {
        int x, int y, int width, int height, bool isPremultiplied) {
    SkAutoLockPixels alp(*bitmap);

    ToColorProc proc = ChooseToColorProc(*bitmap);
    ToColorProc proc = ChooseToColorProc(*bitmap, isPremultiplied);
    if (NULL == proc) {
        return;
    }
@@ -578,13 +651,13 @@ static void Bitmap_getPixels(JNIEnv* env, jobject, const SkBitmap* bitmap,
///////////////////////////////////////////////////////////////////////////////

static void Bitmap_setPixel(JNIEnv* env, jobject, const SkBitmap* bitmap,
                            int x, int y, SkColor color) {
        int x, int y, SkColor color, bool isPremultiplied) {
    SkAutoLockPixels alp(*bitmap);
    if (NULL == bitmap->getPixels()) {
        return;
    }

    FromColorProc proc = ChooseFromColorProc(bitmap->config());
    FromColorProc proc = ChooseFromColorProc(bitmap->config(), isPremultiplied);
    if (NULL == proc) {
        return;
    }
@@ -595,9 +668,9 @@ static void Bitmap_setPixel(JNIEnv* env, jobject, const SkBitmap* bitmap,

static void Bitmap_setPixels(JNIEnv* env, jobject, const SkBitmap* bitmap,
        jintArray pixelArray, int offset, int stride,
                             int x, int y, int width, int height) {
        int x, int y, int width, int height, bool isPremultiplied) {
    GraphicsJNI::SetPixels(env, pixelArray, offset, stride,
                           x, y, width, height, *bitmap);
            x, y, width, height, *bitmap, isPremultiplied);
}

static void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject,
@@ -693,8 +766,6 @@ static JNINativeMethod gBitmapMethods[] = {
    {   "nativeCompress",           "(IIILjava/io/OutputStream;[B)Z",
        (void*)Bitmap_compress },
    {   "nativeErase",              "(II)V", (void*)Bitmap_erase },
    {   "nativeWidth",              "(I)I", (void*)Bitmap_width },
    {   "nativeHeight",             "(I)I", (void*)Bitmap_height },
    {   "nativeRowBytes",           "(I)I", (void*)Bitmap_rowBytes },
    {   "nativeConfig",             "(I)I", (void*)Bitmap_config },
    {   "nativeHasAlpha",           "(I)Z", (void*)Bitmap_hasAlpha },
@@ -709,10 +780,10 @@ static JNINativeMethod gBitmapMethods[] = {
    {   "nativeExtractAlpha",       "(II[I)Landroid/graphics/Bitmap;",
        (void*)Bitmap_extractAlpha },
    {   "nativeGenerationId",       "(I)I", (void*)Bitmap_getGenerationId },
    {   "nativeGetPixel",           "(III)I", (void*)Bitmap_getPixel },
    {   "nativeGetPixels",          "(I[IIIIIII)V", (void*)Bitmap_getPixels },
    {   "nativeSetPixel",           "(IIII)V", (void*)Bitmap_setPixel },
    {   "nativeSetPixels",          "(I[IIIIIII)V", (void*)Bitmap_setPixels },
    {   "nativeGetPixel",           "(IIIZ)I", (void*)Bitmap_getPixel },
    {   "nativeGetPixels",          "(I[IIIIIIIZ)V", (void*)Bitmap_getPixels },
    {   "nativeSetPixel",           "(IIIIZ)V", (void*)Bitmap_setPixel },
    {   "nativeSetPixels",          "(I[IIIIIIIZ)V", (void*)Bitmap_setPixels },
    {   "nativeCopyPixelsToBuffer", "(ILjava/nio/Buffer;)V",
                                            (void*)Bitmap_copyPixelsToBuffer },
    {   "nativeCopyPixelsFromBuffer", "(ILjava/nio/Buffer;)V",
+14 −2
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include "AutoDecodeCancel.h"
#include "Utils.h"
#include "JNIHelp.h"
#include "GraphicsJNI.h"

#include <android_runtime/AndroidRuntime.h>
#include <androidfw/Asset.h>
@@ -25,6 +26,7 @@
jfieldID gOptions_justBoundsFieldID;
jfieldID gOptions_sampleSizeFieldID;
jfieldID gOptions_configFieldID;
jfieldID gOptions_premultipliedFieldID;
jfieldID gOptions_mutableFieldID;
jfieldID gOptions_ditherFieldID;
jfieldID gOptions_purgeableFieldID;
@@ -213,6 +215,7 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
    float scale = 1.0f;
    bool isPurgeable = forcePurgeable || (allowPurgeable && optionsPurgeable(env, options));
    bool preferQualityOverSpeed = false;
    bool requireUnpremultiplied = false;

    jobject javaBitmap = NULL;

@@ -233,6 +236,7 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
        doDither = env->GetBooleanField(options, gOptions_ditherFieldID);
        preferQualityOverSpeed = env->GetBooleanField(options,
                gOptions_preferQualityOverSpeedFieldID);
        requireUnpremultiplied = !env->GetBooleanField(options, gOptions_premultipliedFieldID);
        javaBitmap = env->GetObjectField(options, gOptions_bitmapFieldID);

        if (env->GetBooleanField(options, gOptions_scaledFieldID)) {
@@ -256,6 +260,7 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
    decoder->setSampleSize(sampleSize);
    decoder->setDitherImage(doDither);
    decoder->setPreferQualityOverSpeed(preferQualityOverSpeed);
    decoder->setRequireUnpremultipliedColors(requireUnpremultiplied);

    SkBitmap* outputBitmap = NULL;
    unsigned int existingBufferSize = 0;
@@ -434,14 +439,20 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
    adb.detach();

    if (javaBitmap != NULL) {
        GraphicsJNI::reinitBitmap(env, javaBitmap);
        bool isPremultiplied = !requireUnpremultiplied;
        GraphicsJNI::reinitBitmap(env, javaBitmap, outputBitmap, isPremultiplied);
        outputBitmap->notifyPixelsChanged();
        // If a java bitmap was passed in for reuse, pass it back
        return javaBitmap;
    }

    int bitmapCreateFlags = 0x0;
    if (isMutable) bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Mutable;
    if (!requireUnpremultiplied) bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Premultiplied;

    // now create the java bitmap
    return GraphicsJNI::createBitmap(env, outputBitmap, javaAllocator.getStorageObj(),
            isMutable, ninePatchChunk, layoutBounds, -1);
            bitmapCreateFlags, ninePatchChunk, layoutBounds, -1);
}

static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
@@ -624,6 +635,7 @@ int register_android_graphics_BitmapFactory(JNIEnv* env) {
    gOptions_sampleSizeFieldID = getFieldIDCheck(env, options_class, "inSampleSize", "I");
    gOptions_configFieldID = getFieldIDCheck(env, options_class, "inPreferredConfig",
            "Landroid/graphics/Bitmap$Config;");
    gOptions_premultipliedFieldID = getFieldIDCheck(env, options_class, "inPremultiplied", "Z");
    gOptions_mutableFieldID = getFieldIDCheck(env, options_class, "inMutable", "Z");
    gOptions_ditherFieldID = getFieldIDCheck(env, options_class, "inDither", "Z");
    gOptions_purgeableFieldID = getFieldIDCheck(env, options_class, "inPurgeable", "Z");
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ extern jclass gOptions_class;
extern jfieldID gOptions_justBoundsFieldID;
extern jfieldID gOptions_sampleSizeFieldID;
extern jfieldID gOptions_configFieldID;
extern jfieldID gOptions_premultipliedFieldID;
extern jfieldID gOptions_ditherFieldID;
extern jfieldID gOptions_purgeableFieldID;
extern jfieldID gOptions_shareableFieldID;
Loading