summaryrefslogtreecommitdiffstats
path: root/core/jni/android/graphics
diff options
context:
space:
mode:
authorLeon Scroggins III <scroggo@google.com>2014-02-10 20:30:50 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-02-10 20:30:50 +0000
commit3393f390a5145056f9d67a2357125bd995fceac7 (patch)
tree271e2eb6826c7445dcf1d3f0d4e992d7938e9c46 /core/jni/android/graphics
parenteaddb849629b6585d7c11699bb7a1f0d2b984783 (diff)
parent2826e5f20295a1adb3b341c8b32f27d748e2ee19 (diff)
downloadframeworks_base-3393f390a5145056f9d67a2357125bd995fceac7.zip
frameworks_base-3393f390a5145056f9d67a2357125bd995fceac7.tar.gz
frameworks_base-3393f390a5145056f9d67a2357125bd995fceac7.tar.bz2
Merge "Decode file descriptor from the correct offset."
Diffstat (limited to 'core/jni/android/graphics')
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp63
1 files changed, 42 insertions, 21 deletions
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 3e1f26a..fae93ba 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -474,6 +474,12 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
bitmapCreateFlags, ninePatchChunk, layoutBounds, -1);
}
+// Need to buffer enough input to be able to rewind as much as might be read by a decoder
+// trying to determine the stream's format. Currently the most is 64, read by
+// SkImageDecoder_libwebp.
+// FIXME: Get this number from SkImageDecoder
+#define BYTES_TO_BUFFER 64
+
static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
jobject padding, jobject options) {
@@ -481,11 +487,8 @@ static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteA
SkAutoTUnref<SkStream> stream(CreateJavaInputStreamAdaptor(env, is, storage));
if (stream.get()) {
- // Need to buffer enough input to be able to rewind as much as might be read by a decoder
- // trying to determine the stream's format. Currently the most is 64, read by
- // SkImageDecoder_libwebp.
- // FIXME: Get this number from SkImageDecoder
- SkAutoTUnref<SkStreamRewindable> bufferedStream(SkFrontBufferedStream::Create(stream, 64));
+ SkAutoTUnref<SkStreamRewindable> bufferedStream(
+ SkFrontBufferedStream::Create(stream, BYTES_TO_BUFFER));
SkASSERT(bufferedStream.get() != NULL);
// for now we don't allow purgeable with java inputstreams
bitmap = doDecode(env, bufferedStream, padding, options, false, false);
@@ -506,30 +509,48 @@ static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fi
return nullObjectReturn("fstat return -1");
}
- bool isPurgeable = optionsPurgeable(env, bitmapFactoryOptions);
- bool isShareable = optionsShareable(env, bitmapFactoryOptions);
- bool weOwnTheFD = false;
- if (isPurgeable && isShareable) {
- int newFD = ::dup(descriptor);
- if (-1 != newFD) {
- weOwnTheFD = true;
- descriptor = newFD;
- }
- }
+ // Restore the descriptor's offset on exiting this function.
+ AutoFDSeek autoRestore(descriptor);
FILE* file = fdopen(descriptor, "r");
if (file == NULL) {
return nullObjectReturn("Could not open file");
}
- SkAutoTUnref<SkFILEStream> stream(new SkFILEStream(file,
- weOwnTheFD ? SkFILEStream::kCallerPasses_Ownership :
+ SkAutoTUnref<SkFILEStream> fileStream(new SkFILEStream(file,
SkFILEStream::kCallerRetains_Ownership));
- /* Allow purgeable iff we own the FD, i.e., in the puregeable and
- shareable case.
- */
- return doDecode(env, stream, padding, bitmapFactoryOptions, weOwnTheFD);
+ SkAutoTUnref<SkStreamRewindable> stream;
+
+ // Retain the old behavior of allowing purgeable if both purgeable and
+ // shareable are set to true.
+ bool isPurgeable = optionsPurgeable(env, bitmapFactoryOptions)
+ && optionsShareable(env, bitmapFactoryOptions);
+ if (isPurgeable) {
+ // Copy the stream, so the image can be decoded multiple times without
+ // continuing to modify the original file descriptor.
+ // Copy beginning from the current position.
+ const size_t fileSize = fileStream->getLength() - fileStream->getPosition();
+ void* buffer = sk_malloc_flags(fileSize, 0);
+ if (buffer == NULL) {
+ return nullObjectReturn("Could not make a copy for ashmem");
+ }
+
+ SkAutoTUnref<SkData> data(SkData::NewFromMalloc(buffer, fileSize));
+
+ if (fileStream->read(buffer, fileSize) != fileSize) {
+ return nullObjectReturn("Could not read the file.");
+ }
+
+ stream.reset(new SkMemoryStream(data));
+ } else {
+ // Use a buffered stream. Although an SkFILEStream can be rewound, this
+ // ensures that SkImageDecoder::Factory never rewinds beyond the
+ // current position of the file descriptor.
+ stream.reset(SkFrontBufferedStream::Create(fileStream, BYTES_TO_BUFFER));
+ }
+
+ return doDecode(env, stream, padding, bitmapFactoryOptions, isPurgeable);
}
static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jlong native_asset,