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 196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkBitmap.h" 205827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger#include "SkData.h" 216b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkImageEncoder.h" 226b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "GraphicsJNI.h" 236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkUtils.h" 246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkTemplates.h" 256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkPixelRef.h" 266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "SkStream.h" 276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "BitmapFactory.h" 286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "AutoDecodeCancel.h" 296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "CreateJavaOutputStreamAdaptor.h" 306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "Utils.h" 31a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes#include "JNIHelp.h" 326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include <android_runtime/AndroidRuntime.h> 346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "android_util_Binder.h" 356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "android_nio_utils.h" 366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include "CreateJavaOutputStreamAdaptor.h" 376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include <binder/Parcel.h> 396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include <jni.h> 40b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/Asset.h> 416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include <sys/stat.h> 426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#if 0 446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen #define TRACE_BITMAP(code) code 456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#else 466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen #define TRACE_BITMAP(code) 476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#endif 486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenusing namespace android; 506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 515827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenbergerclass SkBitmapRegionDecoder { 525827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenbergerpublic: 535827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkBitmapRegionDecoder(SkImageDecoder* decoder, int width, int height) { 545827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger fDecoder = decoder; 555827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger fWidth = width; 565827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger fHeight = height; 575827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger } 585827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger ~SkBitmapRegionDecoder() { 595827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkDELETE(fDecoder); 605827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger } 615827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger 625827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger bool decodeRegion(SkBitmap* bitmap, const SkIRect& rect, 6342a1d08df7d417fd4e67eabc91ff05ee77fd9995Mike Reed SkColorType pref, int sampleSize) { 645827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger fDecoder->setSampleSize(sampleSize); 65cc11f15f76a62ded3e403cb2bc818c6aa5bf261cLeon Scroggins return fDecoder->decodeSubset(bitmap, rect, pref); 665827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger } 675827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger 685827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkImageDecoder* getDecoder() const { return fDecoder; } 695827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger int getWidth() const { return fWidth; } 705827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger int getHeight() const { return fHeight; } 715827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger 725827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenbergerprivate: 735827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkImageDecoder* fDecoder; 745827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger int fWidth; 755827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger int fHeight; 765827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger}; 775827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger 78ed79ff0026a44741237a6eb5e3810dbf5d765154Derek Sollenbergerstatic jobject createBitmapRegionDecoder(JNIEnv* env, SkStreamRewindable* stream) { 796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen SkImageDecoder* decoder = SkImageDecoder::Factory(stream); 806b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int width, height; 816b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (NULL == decoder) { 826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen doThrowIOE(env, "Image format not supported"); 836b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nullObjectReturn("SkImageDecoder::Factory returned null"); 846b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 856b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 86e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy JavaPixelAllocator *javaAllocator = new JavaPixelAllocator(env); 876b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen decoder->setAllocator(javaAllocator); 886b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen javaAllocator->unref(); 896b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 906b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (!decoder->buildTileIndex(stream, &width, &height)) { 916b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen char msg[100]; 926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen snprintf(msg, sizeof(msg), "Image failed to decode using %s decoder", 936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen decoder->getFormatName()); 946b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen doThrowIOE(env, msg); 955827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkDELETE(decoder); 966b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nullObjectReturn("decoder->buildTileIndex returned false"); 976b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 986b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 995827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkBitmapRegionDecoder *bm = new SkBitmapRegionDecoder(decoder, width, height); 1006b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return GraphicsJNI::createBitmapRegionDecoder(env, bm); 1016b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 1026b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1036b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray byteArray, 104b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat jint offset, jint length, jboolean isShareable) { 1056b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /* If isShareable we could decide to just wrap the java array and 1066b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen share it, but that means adding a globalref to the java array object 1076b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen For now we just always copy the array's data if isShareable. 1086b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1096b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen AutoJavaByteArray ar(env, byteArray); 110ed79ff0026a44741237a6eb5e3810dbf5d765154Derek Sollenberger SkMemoryStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true); 1115827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger 1125827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger jobject brd = createBitmapRegionDecoder(env, stream); 1135827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkSafeUnref(stream); // the decoder now holds a reference 1145827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger return brd; 1156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 1166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jobject nativeNewInstanceFromFileDescriptor(JNIEnv* env, jobject clazz, 1186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen jobject fileDescriptor, jboolean isShareable) { 1196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen NPE_CHECK_RETURN_ZERO(env, fileDescriptor); 1206b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 121a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes jint descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor); 1225827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger 1236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen struct stat fdStat; 1246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (fstat(descriptor, &fdStat) == -1) { 1256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen doThrowIOE(env, "broken file descriptor"); 1266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nullObjectReturn("fstat return -1"); 1276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1295827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkAutoTUnref<SkData> data(SkData::NewFromFD(descriptor)); 1305827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkMemoryStream* stream = new SkMemoryStream(data); 1316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1325827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger jobject brd = createBitmapRegionDecoder(env, stream); 1335827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger SkSafeUnref(stream); // the decoder now holds a reference 1345827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger return brd; 1356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 1366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jobject nativeNewInstanceFromStream(JNIEnv* env, jobject clazz, 1386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen jobject is, // InputStream 1396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen jbyteArray storage, // byte[] 1406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen jboolean isShareable) { 1415827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger jobject brd = NULL; 142ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III // for now we don't allow shareable with java inputstreams 143c7797525084ba0ea441e394aa0a2ba35d6ff3320Leon Scroggins III SkStreamRewindable* stream = CopyJavaInputStream(env, is, storage); 1446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (stream) { 146ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III brd = createBitmapRegionDecoder(env, stream); 147ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III stream->unref(); // the decoder now holds a reference 1486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1495827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger return brd; 1506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 1516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jobject nativeNewInstanceFromAsset(JNIEnv* env, jobject clazz, 153b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat jlong native_asset, // Asset 1546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen jboolean isShareable) { 1556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen Asset* asset = reinterpret_cast<Asset*>(native_asset); 156ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III SkAutoTUnref<SkMemoryStream> stream(CopyAssetToStream(asset)); 157ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III if (NULL == stream.get()) { 158ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III return NULL; 159ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III } 1605827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger 161ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III jobject brd = createBitmapRegionDecoder(env, stream.get()); 162ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III // The decoder now holds a reference to stream. 1635827cb5059ed0eec4c73adf1acbd7ee47b2c5c8fDerek Sollenberger return brd; 1646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 1656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen/* 1676b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * nine patch not supported 1686b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 1696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * purgeable not supported 1706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * reportSizeToVM not supported 1716b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 172b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhatstatic jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, 173b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat jint start_x, jint start_y, jint width, jint height, jobject options) { 174b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat SkBitmapRegionDecoder *brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle); 175f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin jobject tileBitmap = NULL; 1766b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen SkImageDecoder *decoder = brd->getDecoder(); 1776b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int sampleSize = 1; 17842a1d08df7d417fd4e67eabc91ff05ee77fd9995Mike Reed SkColorType prefColorType = kUnknown_SkColorType; 1796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen bool doDither = true; 180953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen bool preferQualityOverSpeed = false; 1811abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik bool requireUnpremultiplied = false; 1826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1836b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (NULL != options) { 1846b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID); 1856b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // initialize these, in case we fail later on 1866b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen env->SetIntField(options, gOptions_widthFieldID, -1); 1876b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen env->SetIntField(options, gOptions_heightFieldID, -1); 1886b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen env->SetObjectField(options, gOptions_mimeFieldID, 0); 1896b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1906b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen jobject jconfig = env->GetObjectField(options, gOptions_configFieldID); 19142a1d08df7d417fd4e67eabc91ff05ee77fd9995Mike Reed prefColorType = GraphicsJNI::getNativeBitmapColorType(env, jconfig); 1926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen doDither = env->GetBooleanField(options, gOptions_ditherFieldID); 193953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen preferQualityOverSpeed = env->GetBooleanField(options, 194953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen gOptions_preferQualityOverSpeedFieldID); 195f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin // Get the bitmap for re-use if it exists. 196f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin tileBitmap = env->GetObjectField(options, gOptions_bitmapFieldID); 1972cc409ae52a2a50f54195579a000e98f403de9beLeon Scroggins III requireUnpremultiplied = !env->GetBooleanField(options, gOptions_premultipliedFieldID); 1986b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1996b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2006b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen decoder->setDitherImage(doDither); 201953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen decoder->setPreferQualityOverSpeed(preferQualityOverSpeed); 2021abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik decoder->setRequireUnpremultipliedColors(requireUnpremultiplied); 2031abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik AutoDecoderCancel adc(options, decoder); 2046b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2056b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // To fix the race condition in case "requestCancelDecode" 2066b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // happens earlier than AutoDecoderCancel object is added 2076b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // to the gAutoDecoderCancelMutex linked list. 2086b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (NULL != options && env->GetBooleanField(options, gOptions_mCancelID)) { 2096b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nullObjectReturn("gOptions_mCancelID");; 2106b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen SkIRect region; 2136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen region.fLeft = start_x; 2146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen region.fTop = start_y; 2156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen region.fRight = start_x + width; 2166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen region.fBottom = start_y + height; 217f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin SkBitmap* bitmap = NULL; 218f5b43bdc6231df8b646d5bbb215e639230f37260Mike Klein SkAutoTDelete<SkBitmap> adb; 219f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin 220f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin if (tileBitmap != NULL) { 221f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin // Re-use bitmap. 222f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin bitmap = GraphicsJNI::getNativeBitmap(env, tileBitmap); 223f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin } 224f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin if (bitmap == NULL) { 225f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin bitmap = new SkBitmap; 226f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin adb.reset(bitmap); 227f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin } 2286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 22942a1d08df7d417fd4e67eabc91ff05ee77fd9995Mike Reed if (!brd->decodeRegion(bitmap, region, prefColorType, sampleSize)) { 2306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nullObjectReturn("decoder->decodeRegion returned false"); 2316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // update options (if any) 2346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (NULL != options) { 2356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen env->SetIntField(options, gOptions_widthFieldID, bitmap->width()); 2366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen env->SetIntField(options, gOptions_heightFieldID, bitmap->height()); 2376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // TODO: set the mimeType field with the data from the codec. 2386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // but how to reuse a set of strings, rather than allocating new one 2396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // each time? 2406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen env->SetObjectField(options, gOptions_mimeFieldID, 2416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen getMimeTypeString(env, decoder->getFormat())); 2426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 244f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin if (tileBitmap != NULL) { 2453b47713b26859f83c0cf7adede8e8090097673adChris Craik bitmap->notifyPixelsChanged(); 246f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin return tileBitmap; 247f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin } 2486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 249f970c2e6de52ef0da91c3c8f3b48a44303d0eb73Owen Lin // detach bitmap from its autodeleter, since we want to own it now 250f5b43bdc6231df8b646d5bbb215e639230f37260Mike Klein adb.detach(); 251e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy 252afde46ed008f150e45e1b0d7e1dc588fc047b74fPatrick Dubroy JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator(); 253afde46ed008f150e45e1b0d7e1dc588fc047b74fPatrick Dubroy jbyteArray buff = allocator->getStorageObjAndReset(); 2541abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik 2551abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik int bitmapCreateFlags = 0; 2561abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik if (!requireUnpremultiplied) bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Premultiplied; 2571abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik return GraphicsJNI::createBitmap(env, bitmap, buff, bitmapCreateFlags, NULL, NULL, -1); 2586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 2596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 260b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhatstatic jint nativeGetHeight(JNIEnv* env, jobject, jlong brdHandle) { 261b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat SkBitmapRegionDecoder *brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle); 262b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat return static_cast<jint>(brd->getHeight()); 2636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 2646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 265b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhatstatic jint nativeGetWidth(JNIEnv* env, jobject, jlong brdHandle) { 266b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat SkBitmapRegionDecoder *brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle); 267b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat return static_cast<jint>(brd->getWidth()); 2686b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 2696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 270b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhatstatic void nativeClean(JNIEnv* env, jobject, jlong brdHandle) { 271b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat SkBitmapRegionDecoder *brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle); 2726b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen delete brd; 2736b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 2746b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2756b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen/////////////////////////////////////////////////////////////////////////////// 2766b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2776b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#include <android_runtime/AndroidRuntime.h> 2786b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic JNINativeMethod gBitmapRegionDecoderMethods[] = { 2806b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen { "nativeDecodeRegion", 281b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat "(JIIIILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;", 2826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen (void*)nativeDecodeRegion}, 2836b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 284b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat { "nativeGetHeight", "(J)I", (void*)nativeGetHeight}, 2856b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 286b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat { "nativeGetWidth", "(J)I", (void*)nativeGetWidth}, 2876b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 288b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat { "nativeClean", "(J)V", (void*)nativeClean}, 2896b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2906b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen { "nativeNewInstance", 2916b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen "([BIIZ)Landroid/graphics/BitmapRegionDecoder;", 2926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen (void*)nativeNewInstanceFromByteArray 2936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen }, 2946b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2956b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen { "nativeNewInstance", 2966b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen "(Ljava/io/InputStream;[BZ)Landroid/graphics/BitmapRegionDecoder;", 2976b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen (void*)nativeNewInstanceFromStream 2986b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen }, 2996b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 3006b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen { "nativeNewInstance", 3016b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen "(Ljava/io/FileDescriptor;Z)Landroid/graphics/BitmapRegionDecoder;", 3026b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen (void*)nativeNewInstanceFromFileDescriptor 3036b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen }, 3046b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 3056b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen { "nativeNewInstance", 306b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat "(JZ)Landroid/graphics/BitmapRegionDecoder;", 3076b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen (void*)nativeNewInstanceFromAsset 3086b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen }, 3096b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen}; 3106b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 3116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen#define kClassPathName "android/graphics/BitmapRegionDecoder" 3126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 3136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenint register_android_graphics_BitmapRegionDecoder(JNIEnv* env) 3146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen{ 3156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return android::AndroidRuntime::registerNativeMethods(env, kClassPathName, 3166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen gBitmapRegionDecoderMethods, SK_ARRAY_COUNT(gBitmapRegionDecoderMethods)); 3176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 318