16b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen/*
26b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Copyright (C) 2010 The Android Open Source Project
36b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen *
46b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License");
56b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * you may not use this file except in compliance with the License.
66b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * You may obtain a copy of the License at
76b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen *
86b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen *      http://www.apache.org/licenses/LICENSE-2.0
96b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen *
106b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Unless required by applicable law or agreed to in writing, software
116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS,
126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * See the License for the specific language governing permissions and
146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * limitations under the License.
156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */
166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#define LOG_TAG "BitmapRegionDecoder"
186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
1960126efd7d905ca24822765c6dafac17fef278abBen Wagner#include "BitmapFactory.h"
2060126efd7d905ca24822765c6dafac17fef278abBen Wagner#include "CreateJavaOutputStreamAdaptor.h"
211f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett#include "GraphicsJNI.h"
221f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett#include "Utils.h"
231f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett
246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkBitmap.h"
251f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett#include "SkBitmapRegionDecoder.h"
261f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett#include "SkCodec.h"
275827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger#include "SkData.h"
286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkUtils.h"
296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkPixelRef.h"
306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkStream.h"
311f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett
326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "android_nio_utils.h"
3360126efd7d905ca24822765c6dafac17fef278abBen Wagner#include "android_util_Binder.h"
3460126efd7d905ca24822765c6dafac17fef278abBen Wagner#include "core_jni_helpers.h"
356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
3660126efd7d905ca24822765c6dafac17fef278abBen Wagner#include <JNIHelp.h>
3760126efd7d905ca24822765c6dafac17fef278abBen Wagner#include <androidfw/Asset.h>
386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include <binder/Parcel.h>
396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include <jni.h>
406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include <sys/stat.h>
416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenusing namespace android;
436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
443449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III// Takes ownership of the SkStreamRewindable. For consistency, deletes stream even
453449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III// when returning null.
46ed79ff0026a44741237a6eb5e3810dbf5d765154Derek Sollenbergerstatic jobject createBitmapRegionDecoder(JNIEnv* env, SkStreamRewindable* stream) {
471f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    SkAutoTDelete<SkBitmapRegionDecoder> brd(
481f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett            SkBitmapRegionDecoder::Create(stream, SkBitmapRegionDecoder::kAndroidCodec_Strategy));
491f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    if (NULL == brd) {
506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        doThrowIOE(env, "Image format not supported");
511f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        return nullObjectReturn("CreateBitmapRegionDecoder returned null");
526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    }
536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
541f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    return GraphicsJNI::createBitmapRegionDecoder(env, brd.detach());
556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray byteArray,
58b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat                                     jint offset, jint length, jboolean isShareable) {
596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    /*  If isShareable we could decide to just wrap the java array and
606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        share it, but that means adding a globalref to the java array object
616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        For now we just always copy the array's data if isShareable.
626b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen     */
636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    AutoJavaByteArray ar(env, byteArray);
64ed79ff0026a44741237a6eb5e3810dbf5d765154Derek Sollenberger    SkMemoryStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
655827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger
663449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III    // the decoder owns the stream.
675827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger    jobject brd = createBitmapRegionDecoder(env, stream);
685827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger    return brd;
696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
716b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jobject nativeNewInstanceFromFileDescriptor(JNIEnv* env, jobject clazz,
726b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen                                          jobject fileDescriptor, jboolean isShareable) {
736b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    NPE_CHECK_RETURN_ZERO(env, fileDescriptor);
746b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
75a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes    jint descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor);
765827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger
776b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    struct stat fdStat;
786b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    if (fstat(descriptor, &fdStat) == -1) {
796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        doThrowIOE(env, "broken file descriptor");
806b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        return nullObjectReturn("fstat return -1");
816b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    }
826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
835827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger    SkAutoTUnref<SkData> data(SkData::NewFromFD(descriptor));
845827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger    SkMemoryStream* stream = new SkMemoryStream(data);
856b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
863449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III    // the decoder owns the stream.
875827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger    jobject brd = createBitmapRegionDecoder(env, stream);
885827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger    return brd;
896b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
906b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
916b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jobject nativeNewInstanceFromStream(JNIEnv* env, jobject clazz,
926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen                                  jobject is,       // InputStream
936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen                                  jbyteArray storage, // byte[]
946b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen                                  jboolean isShareable) {
955827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger    jobject brd = NULL;
96ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III    // for now we don't allow shareable with java inputstreams
97c7797525084ba0ea441e394aa0a2ba35d6ff3320Leon Scroggins III    SkStreamRewindable* stream = CopyJavaInputStream(env, is, storage);
986b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
996b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    if (stream) {
1003449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III        // the decoder owns the stream.
101ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III        brd = createBitmapRegionDecoder(env, stream);
1026b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    }
1035827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger    return brd;
1046b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
1056b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
1066b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jobject nativeNewInstanceFromAsset(JNIEnv* env, jobject clazz,
107b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat                                 jlong native_asset, // Asset
1086b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen                                 jboolean isShareable) {
1096b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    Asset* asset = reinterpret_cast<Asset*>(native_asset);
1103449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III    SkMemoryStream* stream = CopyAssetToStream(asset);
1113449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III    if (NULL == stream) {
112ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III        return NULL;
113ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III    }
1145827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger
1153449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III    // the decoder owns the stream.
1163449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III    jobject brd = createBitmapRegionDecoder(env, stream);
1175827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger    return brd;
1186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
1196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
1206b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen/*
1216b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * nine patch not supported
1226b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * purgeable not supported
1236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * reportSizeToVM not supported
1246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */
1251f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarettstatic jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, jint inputX,
1261f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        jint inputY, jint inputWidth, jint inputHeight, jobject options) {
1271f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett
1281f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // Set default options.
1296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    int sampleSize = 1;
1301f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    SkColorType colorType = kN32_SkColorType;
1311f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    bool requireUnpremul = false;
1321f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    jobject javaBitmap = NULL;
1336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
1341f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // Update the default options with any options supplied by the client.
1356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    if (NULL != options) {
1366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID);
1371f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        jobject jconfig = env->GetObjectField(options, gOptions_configFieldID);
1381f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        colorType = GraphicsJNI::getNativeBitmapColorType(env, jconfig);
1391f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        requireUnpremul = !env->GetBooleanField(options, gOptions_premultipliedFieldID);
1401f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        javaBitmap = env->GetObjectField(options, gOptions_bitmapFieldID);
1411f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        // The Java options of ditherMode and preferQualityOverSpeed are deprecated.  We will
1421f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        // ignore the values of these fields.
1431f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett
1441f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        // Initialize these fields to indicate a failure.  If the decode succeeds, we
1451f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        // will update them later on.
1466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        env->SetIntField(options, gOptions_widthFieldID, -1);
1476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        env->SetIntField(options, gOptions_heightFieldID, -1);
1486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        env->SetObjectField(options, gOptions_mimeFieldID, 0);
1496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    }
1506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
1511f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // Recycle a bitmap if possible.
1521f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    android::Bitmap* recycledBitmap = nullptr;
1531f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    size_t recycledBytes = 0;
1541f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    if (javaBitmap) {
1551f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        recycledBitmap = GraphicsJNI::getBitmap(env, javaBitmap);
1561f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        if (recycledBitmap->peekAtPixelRef()->isImmutable()) {
1571f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett            ALOGW("Warning: Reusing an immutable bitmap as an image decoder target.");
1581f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        }
1591f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        recycledBytes = GraphicsJNI::getBitmapAllocationByteCount(env, javaBitmap);
1606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    }
1616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
1621f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // Set up the pixel allocator
1631f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    SkBRDAllocator* allocator = nullptr;
1641f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    RecyclingClippingPixelAllocator recycleAlloc(recycledBitmap, recycledBytes);
1651f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    JavaPixelAllocator javaAlloc(env);
1661f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    if (javaBitmap) {
1671f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        allocator = &recycleAlloc;
1681f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        // We are required to match the color type of the recycled bitmap.
1691f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        colorType = recycledBitmap->info().colorType();
1701f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    } else {
1711f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        allocator = &javaAlloc;
172f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin    }
1736b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
1741f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // Decode the region.
1751f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    SkIRect subset = SkIRect::MakeXYWH(inputX, inputY, inputWidth, inputHeight);
1761f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    SkBitmapRegionDecoder* brd =
1771f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett            reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
1781f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    SkBitmap bitmap;
1791f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    if (!brd->decodeRegion(&bitmap, allocator, subset, sampleSize, colorType, requireUnpremul)) {
1801f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        return nullObjectReturn("Failed to decode region.");
1816b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    }
1826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
1831f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // If the client provided options, indicate that the decode was successful.
1846b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    if (NULL != options) {
185f29ed28c7b878ef28058bc730715d0d32445bc57John Reck        env->SetIntField(options, gOptions_widthFieldID, bitmap.width());
186f29ed28c7b878ef28058bc730715d0d32445bc57John Reck        env->SetIntField(options, gOptions_heightFieldID, bitmap.height());
1876b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        env->SetObjectField(options, gOptions_mimeFieldID,
1881f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett                encodedFormatToString(env, brd->getEncodedFormat()));
189d31512b9a6d9d6913b1d45ad2fb029a98c1804bfMatt Sarett        if (env->ExceptionCheck()) {
190d31512b9a6d9d6913b1d45ad2fb029a98c1804bfMatt Sarett            return nullObjectReturn("OOM in encodedFormatToString()");
191d31512b9a6d9d6913b1d45ad2fb029a98c1804bfMatt Sarett        }
1926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    }
1936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
1941f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // If we may have reused a bitmap, we need to indicate that the pixels have changed.
1951f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    if (javaBitmap) {
1961f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        recycleAlloc.copyIfNecessary();
1971f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        return javaBitmap;
198f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin    }
1996b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
2001abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    int bitmapCreateFlags = 0;
2011f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    if (!requireUnpremul) {
2021f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Premultiplied;
2031f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    }
2041f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    return GraphicsJNI::createBitmap(env, javaAlloc.getStorageObjAndReset(), bitmapCreateFlags);
2056b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
2066b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
207b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhatstatic jint nativeGetHeight(JNIEnv* env, jobject, jlong brdHandle) {
2081f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    SkBitmapRegionDecoder* brd =
2091f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett            reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
2101f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    return static_cast<jint>(brd->height());
2116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
2126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
213b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhatstatic jint nativeGetWidth(JNIEnv* env, jobject, jlong brdHandle) {
2141f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    SkBitmapRegionDecoder* brd =
2151f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett            reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
2161f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    return static_cast<jint>(brd->width());
2176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
2186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
219b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhatstatic void nativeClean(JNIEnv* env, jobject, jlong brdHandle) {
2201f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    SkBitmapRegionDecoder* brd =
2211f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett            reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
2226b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    delete brd;
2236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
2246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
2256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen///////////////////////////////////////////////////////////////////////////////
2266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
22776f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gBitmapRegionDecoderMethods[] = {
2286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    {   "nativeDecodeRegion",
229b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat        "(JIIIILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;",
2306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        (void*)nativeDecodeRegion},
2316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
232b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat    {   "nativeGetHeight", "(J)I", (void*)nativeGetHeight},
2336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
234b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat    {   "nativeGetWidth", "(J)I", (void*)nativeGetWidth},
2356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
236b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat    {   "nativeClean", "(J)V", (void*)nativeClean},
2376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
2386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    {   "nativeNewInstance",
2396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        "([BIIZ)Landroid/graphics/BitmapRegionDecoder;",
2406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        (void*)nativeNewInstanceFromByteArray
2416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    },
2426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
2436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    {   "nativeNewInstance",
2446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        "(Ljava/io/InputStream;[BZ)Landroid/graphics/BitmapRegionDecoder;",
2456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        (void*)nativeNewInstanceFromStream
2466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    },
2476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
2486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    {   "nativeNewInstance",
2496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        "(Ljava/io/FileDescriptor;Z)Landroid/graphics/BitmapRegionDecoder;",
2506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        (void*)nativeNewInstanceFromFileDescriptor
2516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    },
2526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
2536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    {   "nativeNewInstance",
254b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat        "(JZ)Landroid/graphics/BitmapRegionDecoder;",
2556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen        (void*)nativeNewInstanceFromAsset
2566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen    },
2576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen};
2586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen
2596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenint register_android_graphics_BitmapRegionDecoder(JNIEnv* env)
2606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen{
261ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    return android::RegisterMethodsOrDie(env, "android/graphics/BitmapRegionDecoder",
262ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe            gBitmapRegionDecoderMethods, NELEM(gBitmapRegionDecoderMethods));
2636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}
264