diff options
author | Leon Scroggins III <scroggo@google.com> | 2014-02-10 20:30:50 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-02-10 20:30:50 +0000 |
commit | 3393f390a5145056f9d67a2357125bd995fceac7 (patch) | |
tree | 271e2eb6826c7445dcf1d3f0d4e992d7938e9c46 /core/jni/android/graphics | |
parent | eaddb849629b6585d7c11699bb7a1f0d2b984783 (diff) | |
parent | 2826e5f20295a1adb3b341c8b32f27d748e2ee19 (diff) | |
download | frameworks_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.cpp | 63 |
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, |