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

Commit dc70afae authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Add inPremutiplied option to BitmapFactory.Options, functionality in Bitmap" into klp-dev

parents 10fa8c06 1abf5d62
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