Loading core/jni/android/graphics/BitmapFactory.cpp +64 −36 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <utils/ResourceTypes.h> #include <netinet/in.h> #include <sys/mman.h> #include <sys/stat.h> jclass gOptions_class; jfieldID gOptions_justBoundsFieldID; Loading Loading @@ -559,7 +560,27 @@ static void nativeSetDefaultConfig(JNIEnv* env, jobject, int nativeConfig) { } } static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream, bool isShareable) { static SkMemoryStream* buildSkMemoryStream(SkStream *stream) { size_t bufferSize = 4096; size_t streamLen = 0; size_t len; char* data = (char*)sk_malloc_throw(bufferSize); while ((len = stream->read(data + streamLen, bufferSize - streamLen)) != 0) { streamLen += len; if (streamLen == bufferSize) { bufferSize *= 2; data = (char*)sk_realloc_throw(data, bufferSize); } } data = (char*)sk_realloc_throw(data, streamLen); SkMemoryStream* streamMem = new SkMemoryStream(); streamMem->setMemoryOwned(data, streamLen); return streamMem; } static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream) { SkImageDecoder* decoder = SkImageDecoder::Factory(stream); int width, height; if (NULL == decoder) { Loading @@ -574,9 +595,10 @@ static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream, bool isShareable) javaAllocator->unref(); javaMemoryReporter->unref(); if (!decoder->buildTileIndex(stream, &width, &height, isShareable)) { char msg[1024]; snprintf(msg, 1023, "Image failed to decode using %s decoder", decoder->getFormatName()); if (!decoder->buildTileIndex(stream, &width, &height)) { char msg[100]; snprintf(msg, sizeof(msg), "Image failed to decode using %s decoder", decoder->getFormatName()); doThrowIOE(env, msg); return nullObjectReturn("decoder->buildTileIndex returned false"); } Loading @@ -588,13 +610,13 @@ static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream, bool isShareable) static jobject nativeCreateLargeBitmapFromByteArray(JNIEnv* env, jobject, jbyteArray byteArray, int offset, int length, jboolean isShareable) { /* If isShareable we could decide to just wrap the java array and share it, but that means adding a globalref to the java array object For now we just always copy the array's data if isShareable. */ AutoJavaByteArray ar(env, byteArray); SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, false); SkAutoUnref aur(stream); if (isShareable) { aur.detach(); } return doBuildTileIndex(env, stream, isShareable); SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true); return doBuildTileIndex(env, stream); } static jobject nativeCreateLargeBitmapFromFileDescriptor(JNIEnv* env, jobject clazz, Loading @@ -603,24 +625,31 @@ static jobject nativeCreateLargeBitmapFromFileDescriptor(JNIEnv* env, jobject cl jint descriptor = env->GetIntField(fileDescriptor, gFileDescriptor_descriptor); bool weOwnTheFD = false; if (isShareable) { int newFD = ::dup(descriptor); if (-1 != newFD) { weOwnTheFD = true; descriptor = newFD; } SkStream *stream = NULL; struct stat fdStat; int newFD; if (fstat(descriptor, &fdStat) == -1) { doThrowIOE(env, "broken file descriptor"); return nullObjectReturn("fstat return -1"); } if (isShareable && S_ISREG(fdStat.st_mode) && (newFD = ::dup(descriptor)) != -1) { SkFDStream* fdStream = new SkFDStream(newFD, true); if (!fdStream->isValid()) { fdStream->unref(); return NULL; } SkFDStream* stream = new SkFDStream(descriptor, weOwnTheFD); SkAutoUnref aur(stream); if (!stream->isValid()) { stream = fdStream; } else { SkFDStream* fdStream = new SkFDStream(descriptor, false); if (!fdStream->isValid()) { fdStream->unref(); return NULL; } if (isShareable) { aur.detach(); stream = buildSkMemoryStream(fdStream); fdStream->unref(); } /* Restore our offset when we leave, so we can be called more than once Loading @@ -629,7 +658,7 @@ static jobject nativeCreateLargeBitmapFromFileDescriptor(JNIEnv* env, jobject cl */ AutoFDSeek as(descriptor); return doBuildTileIndex(env, stream, isShareable); return doBuildTileIndex(env, stream); } static jobject nativeCreateLargeBitmapFromStream(JNIEnv* env, jobject clazz, Loading @@ -641,7 +670,8 @@ static jobject nativeCreateLargeBitmapFromStream(JNIEnv* env, jobject clazz, if (stream) { // for now we don't allow shareable with java inputstreams largeBitmap = doBuildTileIndex(env, stream, false); SkMemoryStream *mStream = buildSkMemoryStream(stream); largeBitmap = doBuildTileIndex(env, mStream); stream->unref(); } return largeBitmap; Loading @@ -650,14 +680,12 @@ static jobject nativeCreateLargeBitmapFromStream(JNIEnv* env, jobject clazz, static jobject nativeCreateLargeBitmapFromAsset(JNIEnv* env, jobject clazz, jint native_asset, // Asset jboolean isShareable) { SkStream* stream; SkStream* stream, *assStream; Asset* asset = reinterpret_cast<Asset*>(native_asset); stream = new AssetStreamAdaptor(asset); SkAutoUnref aur(stream); if (isShareable) { aur.detach(); } return doBuildTileIndex(env, stream, isShareable); assStream = new AssetStreamAdaptor(asset); stream = buildSkMemoryStream(assStream); assStream->unref(); return doBuildTileIndex(env, stream); } /////////////////////////////////////////////////////////////////////////////// Loading graphics/java/android/graphics/BitmapFactory.java +0 −6 Original line number Diff line number Diff line Loading @@ -628,12 +628,6 @@ public class BitmapFactory { */ public static LargeBitmap createLargeBitmap( FileDescriptor fd, boolean isShareable) throws IOException { if (MemoryFile.isMemoryFile(fd)) { int mappedlength = MemoryFile.getSize(fd); MemoryFile file = new MemoryFile(fd, mappedlength, "r"); InputStream is = file.getInputStream(); return createLargeBitmap(is, isShareable); } return nativeCreateLargeBitmap(fd, isShareable); } Loading Loading
core/jni/android/graphics/BitmapFactory.cpp +64 −36 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <utils/ResourceTypes.h> #include <netinet/in.h> #include <sys/mman.h> #include <sys/stat.h> jclass gOptions_class; jfieldID gOptions_justBoundsFieldID; Loading Loading @@ -559,7 +560,27 @@ static void nativeSetDefaultConfig(JNIEnv* env, jobject, int nativeConfig) { } } static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream, bool isShareable) { static SkMemoryStream* buildSkMemoryStream(SkStream *stream) { size_t bufferSize = 4096; size_t streamLen = 0; size_t len; char* data = (char*)sk_malloc_throw(bufferSize); while ((len = stream->read(data + streamLen, bufferSize - streamLen)) != 0) { streamLen += len; if (streamLen == bufferSize) { bufferSize *= 2; data = (char*)sk_realloc_throw(data, bufferSize); } } data = (char*)sk_realloc_throw(data, streamLen); SkMemoryStream* streamMem = new SkMemoryStream(); streamMem->setMemoryOwned(data, streamLen); return streamMem; } static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream) { SkImageDecoder* decoder = SkImageDecoder::Factory(stream); int width, height; if (NULL == decoder) { Loading @@ -574,9 +595,10 @@ static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream, bool isShareable) javaAllocator->unref(); javaMemoryReporter->unref(); if (!decoder->buildTileIndex(stream, &width, &height, isShareable)) { char msg[1024]; snprintf(msg, 1023, "Image failed to decode using %s decoder", decoder->getFormatName()); if (!decoder->buildTileIndex(stream, &width, &height)) { char msg[100]; snprintf(msg, sizeof(msg), "Image failed to decode using %s decoder", decoder->getFormatName()); doThrowIOE(env, msg); return nullObjectReturn("decoder->buildTileIndex returned false"); } Loading @@ -588,13 +610,13 @@ static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream, bool isShareable) static jobject nativeCreateLargeBitmapFromByteArray(JNIEnv* env, jobject, jbyteArray byteArray, int offset, int length, jboolean isShareable) { /* If isShareable we could decide to just wrap the java array and share it, but that means adding a globalref to the java array object For now we just always copy the array's data if isShareable. */ AutoJavaByteArray ar(env, byteArray); SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, false); SkAutoUnref aur(stream); if (isShareable) { aur.detach(); } return doBuildTileIndex(env, stream, isShareable); SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true); return doBuildTileIndex(env, stream); } static jobject nativeCreateLargeBitmapFromFileDescriptor(JNIEnv* env, jobject clazz, Loading @@ -603,24 +625,31 @@ static jobject nativeCreateLargeBitmapFromFileDescriptor(JNIEnv* env, jobject cl jint descriptor = env->GetIntField(fileDescriptor, gFileDescriptor_descriptor); bool weOwnTheFD = false; if (isShareable) { int newFD = ::dup(descriptor); if (-1 != newFD) { weOwnTheFD = true; descriptor = newFD; } SkStream *stream = NULL; struct stat fdStat; int newFD; if (fstat(descriptor, &fdStat) == -1) { doThrowIOE(env, "broken file descriptor"); return nullObjectReturn("fstat return -1"); } if (isShareable && S_ISREG(fdStat.st_mode) && (newFD = ::dup(descriptor)) != -1) { SkFDStream* fdStream = new SkFDStream(newFD, true); if (!fdStream->isValid()) { fdStream->unref(); return NULL; } SkFDStream* stream = new SkFDStream(descriptor, weOwnTheFD); SkAutoUnref aur(stream); if (!stream->isValid()) { stream = fdStream; } else { SkFDStream* fdStream = new SkFDStream(descriptor, false); if (!fdStream->isValid()) { fdStream->unref(); return NULL; } if (isShareable) { aur.detach(); stream = buildSkMemoryStream(fdStream); fdStream->unref(); } /* Restore our offset when we leave, so we can be called more than once Loading @@ -629,7 +658,7 @@ static jobject nativeCreateLargeBitmapFromFileDescriptor(JNIEnv* env, jobject cl */ AutoFDSeek as(descriptor); return doBuildTileIndex(env, stream, isShareable); return doBuildTileIndex(env, stream); } static jobject nativeCreateLargeBitmapFromStream(JNIEnv* env, jobject clazz, Loading @@ -641,7 +670,8 @@ static jobject nativeCreateLargeBitmapFromStream(JNIEnv* env, jobject clazz, if (stream) { // for now we don't allow shareable with java inputstreams largeBitmap = doBuildTileIndex(env, stream, false); SkMemoryStream *mStream = buildSkMemoryStream(stream); largeBitmap = doBuildTileIndex(env, mStream); stream->unref(); } return largeBitmap; Loading @@ -650,14 +680,12 @@ static jobject nativeCreateLargeBitmapFromStream(JNIEnv* env, jobject clazz, static jobject nativeCreateLargeBitmapFromAsset(JNIEnv* env, jobject clazz, jint native_asset, // Asset jboolean isShareable) { SkStream* stream; SkStream* stream, *assStream; Asset* asset = reinterpret_cast<Asset*>(native_asset); stream = new AssetStreamAdaptor(asset); SkAutoUnref aur(stream); if (isShareable) { aur.detach(); } return doBuildTileIndex(env, stream, isShareable); assStream = new AssetStreamAdaptor(asset); stream = buildSkMemoryStream(assStream); assStream->unref(); return doBuildTileIndex(env, stream); } /////////////////////////////////////////////////////////////////////////////// Loading
graphics/java/android/graphics/BitmapFactory.java +0 −6 Original line number Diff line number Diff line Loading @@ -628,12 +628,6 @@ public class BitmapFactory { */ public static LargeBitmap createLargeBitmap( FileDescriptor fd, boolean isShareable) throws IOException { if (MemoryFile.isMemoryFile(fd)) { int mappedlength = MemoryFile.getSize(fd); MemoryFile file = new MemoryFile(fd, mappedlength, "r"); InputStream is = file.getInputStream(); return createLargeBitmap(is, isShareable); } return nativeCreateLargeBitmap(fd, isShareable); } Loading