Loading core/jni/android/graphics/BitmapFactory.cpp +42 −21 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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); Loading @@ -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, Loading Loading
core/jni/android/graphics/BitmapFactory.cpp +42 −21 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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); Loading @@ -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, Loading