Skip to content

Commit

Permalink
Refactor all across to use EncodedImage class instead of Pair<PooledB…
Browse files Browse the repository at this point in the history
…yteBuffer, ImageTransformMetaData>
  • Loading branch information
lukkm authored and tyronen committed Jun 15, 2015
1 parent 66e99ac commit e32e0a6
Show file tree
Hide file tree
Showing 18 changed files with 432 additions and 462 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.facebook.imagepipeline.gif.GifImage;
import com.facebook.imagepipeline.image.CloseableAnimatedImage;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.image.EncodedImage;
import com.facebook.imagepipeline.memory.PooledByteBuffer;
import com.facebook.imagepipeline.webp.WebPImage;

Expand All @@ -50,34 +51,46 @@ public AnimatedImageFactory(
/**
* Decodes a GIF into a CloseableImage.
*
* @param pooledByteBufferRef native byte array holding the encoded bytes
* @param encodedImage encoded image (native byte array holding the encoded bytes and meta data)
* @param options the options for the decode
* @return a {@link CloseableImage} for the GIF image
*/
public CloseableImage decodeGif(
final CloseableReference<PooledByteBuffer> pooledByteBufferRef,
final EncodedImage encodedImage,
final ImageDecodeOptions options) {
Preconditions.checkState(!options.forceOldAnimationCode);
final PooledByteBuffer input = pooledByteBufferRef.get();
GifImage gifImage = GifImage.create(input.getNativePtr(), input.size());
final CloseableReference<PooledByteBuffer> bytesRef = encodedImage.getByteBufferRef();
Preconditions.checkNotNull(bytesRef);
try {
Preconditions.checkState(!options.forceOldAnimationCode);
final PooledByteBuffer input = bytesRef.get();
GifImage gifImage = GifImage.create(input.getNativePtr(), input.size());

return getCloseableImage(options, gifImage);
return getCloseableImage(options, gifImage);
} finally {
CloseableReference.closeSafely(bytesRef);
}
}

/**
* Decode a WebP into a CloseableImage.
*
* @param pooledByteBufferRef native byte array holding the encoded bytes
* @param encodedImage encoded image (native byte array holding the encoded bytes and meta data)
* @param options the options for the decode
* @return a {@link CloseableImage} for the WebP image
*/
public CloseableImage decodeWebP(
final CloseableReference<PooledByteBuffer> pooledByteBufferRef,
final EncodedImage encodedImage,
final ImageDecodeOptions options) {
Preconditions.checkArgument(!options.forceOldAnimationCode);
final PooledByteBuffer input = pooledByteBufferRef.get();
WebPImage webPImage = WebPImage.create(input.getNativePtr(), input.size());
return getCloseableImage(options, webPImage);
final CloseableReference<PooledByteBuffer> bytesRef = encodedImage.getByteBufferRef();
Preconditions.checkNotNull(bytesRef);
try {
Preconditions.checkArgument(!options.forceOldAnimationCode);
final PooledByteBuffer input = bytesRef.get();
WebPImage webPImage = WebPImage.create(input.getNativePtr(), input.size());
return getCloseableImage(options, webPImage);
} finally {
CloseableReference.closeSafely(bytesRef);
}
}

private CloseableAnimatedImage getCloseableImage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,26 @@

package com.facebook.imagepipeline.bitmaps;

import javax.annotation.concurrent.GuardedBy;

import java.io.IOException;
import java.io.InputStream;

import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;

import com.facebook.common.internal.Preconditions;
import com.facebook.common.references.CloseableReference;
import com.facebook.common.streams.LimitedInputStream;
import com.facebook.common.streams.TailAppendingInputStream;
import com.facebook.imagepipeline.image.EncodedImage;
import com.facebook.imagepipeline.memory.BitmapPool;
import com.facebook.imagepipeline.memory.PooledByteBuffer;
import com.facebook.imagepipeline.memory.PooledByteBufferInputStream;
import com.facebook.imagepipeline.nativecode.Bitmaps;
import com.facebook.imageutils.JfifUtil;

import java.io.IOException;
import java.io.InputStream;

import javax.annotation.concurrent.GuardedBy;

/**
* Bitmap factory for ART VM (Lollipop and up).
*/
Expand Down Expand Up @@ -75,28 +76,30 @@ CloseableReference<Bitmap> createBitmap(int width, int height) {
/**
* Creates a bitmap from encoded bytes.
*
* @param pooledByteBufferRef the reference to the encoded bytes
* @param encodedImage the encoded image with a reference to the encoded bytes
* @return the bitmap
* @throws java.lang.OutOfMemoryError if the Bitmap cannot be allocated
*/
CloseableReference<Bitmap> decodeFromPooledByteBuffer(
CloseableReference<PooledByteBuffer> pooledByteBufferRef) {
return doDecodeStaticImage(new PooledByteBufferInputStream(pooledByteBufferRef.get()));
CloseableReference<Bitmap> decodeFromEncodedImage(EncodedImage encodedImage) {
return doDecodeStaticImage(encodedImage.getInputStream());
}

/**
* Creates a bitmap from encoded JPEG bytes. Supports a partial JPEG image.
*
* @param pooledByteBufferRef the reference to the encoded bytes
* @param encodedImage the encoded image with reference to the encoded bytes
* @param length the number of encoded bytes in the buffer
* @return the bitmap
* @throws java.lang.OutOfMemoryError if the Bitmap cannot be allocated
*/
CloseableReference<Bitmap> decodeJPEGFromPooledByteBuffer(
CloseableReference<PooledByteBuffer> pooledByteBufferRef,
CloseableReference<Bitmap> decodeJPEGFromEncodedImage(
EncodedImage encodedImage,
int length) {
final PooledByteBuffer pooledByteBuffer = pooledByteBufferRef.get();
final InputStream jpegBufferInputStream = new PooledByteBufferInputStream(pooledByteBuffer);
final InputStream jpegBufferInputStream = encodedImage.getInputStream();
// At this point the InputStream from the encoded image should not be null since in the
// pipeline,this comes from a call stack where this was checked before. Also this method needs
// the InputStream to decode the image so this can't be null.
Preconditions.checkNotNull(jpegBufferInputStream);
jpegBufferInputStream.mark(Integer.MAX_VALUE);

boolean isJpegComplete;
Expand All @@ -109,17 +112,23 @@ CloseableReference<Bitmap> decodeJPEGFromPooledByteBuffer(
throw new RuntimeException(ioe);
}

InputStream jpegDataStream = jpegBufferInputStream;
if (pooledByteBuffer.size() > length) {
jpegDataStream = new LimitedInputStream(jpegDataStream, length);
}
if (!isJpegComplete) {
jpegDataStream = new TailAppendingInputStream(jpegDataStream, EOI_TAIL);
final CloseableReference<PooledByteBuffer> bytesRef = encodedImage.getByteBufferRef();
try {
InputStream jpegDataStream = jpegBufferInputStream;
if (bytesRef.get().size() > length) {
jpegDataStream = new LimitedInputStream(jpegDataStream, length);
}
if (!isJpegComplete) {
jpegDataStream = new TailAppendingInputStream(jpegDataStream, EOI_TAIL);
}
return doDecodeStaticImage(jpegDataStream);
} finally {
CloseableReference.closeSafely(bytesRef);
}
return doDecodeStaticImage(jpegDataStream);
}

private CloseableReference<Bitmap> doDecodeStaticImage(InputStream inputStream) {
Preconditions.checkNotNull(inputStream);
inputStream.mark(Integer.MAX_VALUE);
final BitmapFactory.Options options = getDecodeOptionsForStream(inputStream);
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.facebook.common.internal.Throwables;
import com.facebook.common.references.CloseableReference;
import com.facebook.common.references.ResourceReleaser;
import com.facebook.imageformat.ImageFormat;
import com.facebook.imagepipeline.image.EncodedImage;
import com.facebook.imagepipeline.memory.BitmapCounter;
import com.facebook.imagepipeline.memory.BitmapCounterProvider;
import com.facebook.imagepipeline.memory.PooledByteBuffer;
Expand Down Expand Up @@ -71,10 +73,15 @@ public void release(Bitmap value) {
CloseableReference<Bitmap> createBitmap(short width, short height) {
CloseableReference<PooledByteBuffer> jpgRef = mJpegGenerator.generate(width, height);
try {
CloseableReference<Bitmap> bitmapRef =
decodeJPEGFromPooledByteBuffer(jpgRef, jpgRef.get().size());
bitmapRef.get().eraseColor(Color.TRANSPARENT);
return bitmapRef;
EncodedImage encodedImage = new EncodedImage(jpgRef, ImageFormat.JPEG);
try {
CloseableReference<Bitmap> bitmapRef =
decodeJPEGFromEncodedImage(encodedImage, jpgRef.get().size());
bitmapRef.get().eraseColor(Color.TRANSPARENT);
return bitmapRef;
} finally {
EncodedImage.closeSafely(encodedImage);
}
} finally {
jpgRef.close();
}
Expand All @@ -83,51 +90,62 @@ CloseableReference<Bitmap> createBitmap(short width, short height) {
/**
* Creates a bitmap from encoded bytes.
*
* @param pooledByteBufferRef the reference to the encoded bytes
* @param encodedImage the encoded image with reference to the encoded bytes
* @return the bitmap
* @throws TooManyBitmapsException if the pool is full
* @throws java.lang.OutOfMemoryError if the Bitmap cannot be allocated
*/
CloseableReference<Bitmap> decodeFromPooledByteBuffer(
final CloseableReference<PooledByteBuffer> pooledByteBufferRef) {
final PooledByteBuffer pooledByteBuffer = pooledByteBufferRef.get();
CloseableReference<Bitmap> decodeFromEncodedImage(final EncodedImage encodedImage) {
CloseableReference<PooledByteBuffer> bytesRef = encodedImage.getByteBufferRef();
Preconditions.checkNotNull(bytesRef);
final PooledByteBuffer pooledByteBuffer = bytesRef.get();
final int length = pooledByteBuffer.size();
final CloseableReference<byte[]> encodedBytesArrayRef = mSharedByteArray.get(length);
try {
final byte[] encodedBytesArray = encodedBytesArrayRef.get();
pooledByteBuffer.read(0, encodedBytesArray, 0, length);
return doDecodeBitmap(encodedBytesArray, length);
final CloseableReference<byte[]> encodedBytesArrayRef = mSharedByteArray.get(length);
try {
final byte[] encodedBytesArray = encodedBytesArrayRef.get();
pooledByteBuffer.read(0, encodedBytesArray, 0, length);
return doDecodeBitmap(encodedBytesArray, length);
} finally {
CloseableReference.closeSafely(encodedBytesArrayRef);
}
} finally {
encodedBytesArrayRef.close();
CloseableReference.closeSafely(bytesRef);
}
}

/**
* Creates a bitmap from encoded JPEG bytes. Supports a partial JPEG image.
*
* @param pooledByteBufferRef the reference to the encoded bytes
* @param encodedImage the encoded image with reference to the encoded bytes
* @param length the number of encoded bytes in the buffer
* @return the bitmap
* @throws TooManyBitmapsException if the pool is full
* @throws java.lang.OutOfMemoryError if the Bitmap cannot be allocated
*/
CloseableReference<Bitmap> decodeJPEGFromPooledByteBuffer(
final CloseableReference<PooledByteBuffer> pooledByteBufferRef,
CloseableReference<Bitmap> decodeJPEGFromEncodedImage(
final EncodedImage encodedImage,
int length) {
final PooledByteBuffer pooledByteBuffer = pooledByteBufferRef.get();
Preconditions.checkArgument(length <= pooledByteBuffer.size());
// allocate bigger array in case EOI needs to be added
final CloseableReference<byte[]> encodedBytesArrayRef = mSharedByteArray.get(length + 2);
final CloseableReference<PooledByteBuffer> bytesRef = encodedImage.getByteBufferRef();
Preconditions.checkNotNull(bytesRef);
try {
byte[] encodedBytesArray = encodedBytesArrayRef.get();
pooledByteBuffer.read(0, encodedBytesArray, 0, length);
if (!endsWithEOI(encodedBytesArray, length)) {
putEOI(encodedBytesArray, length);
length += 2;
final PooledByteBuffer pooledByteBuffer = bytesRef.get();
Preconditions.checkArgument(length <= pooledByteBuffer.size());
// allocate bigger array in case EOI needs to be added
final CloseableReference<byte[]> encodedBytesArrayRef = mSharedByteArray.get(length + 2);
try {
byte[] encodedBytesArray = encodedBytesArrayRef.get();
pooledByteBuffer.read(0, encodedBytesArray, 0, length);
if (!endsWithEOI(encodedBytesArray, length)) {
putEOI(encodedBytesArray, length);
length += 2;
}
return doDecodeBitmap(encodedBytesArray, length);
} finally {
CloseableReference.closeSafely(encodedBytesArrayRef);
}
return doDecodeBitmap(encodedBytesArray, length);
} finally {
encodedBytesArrayRef.close();
CloseableReference.closeSafely(bytesRef);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import android.os.Build;

import com.facebook.common.references.CloseableReference;
import com.facebook.imagepipeline.memory.PooledByteBuffer;
import com.facebook.imagepipeline.image.EncodedImage;

/**
* Bitmap factory optimized for the platform.
Expand Down Expand Up @@ -74,38 +74,37 @@ public synchronized List<CloseableReference<Bitmap>> associateBitmapsWithBitmapC

/**
* Creates a bitmap from encoded bytes. Supports JPEG but callers should use
* {@link #decodeJPEGFromPooledByteBuffer} for partial JPEGs.
* {@link #decodeJPEGFromEncodedImage} for partial JPEGs.
*
* @param pooledByteBufferRef the reference to the encoded bytes
* @param encodedImage the reference to the encoded image with the reference to the encoded bytes
* @return the bitmap
* @throws TooManyBitmapsException if the pool is full
* @throws java.lang.OutOfMemoryError if the Bitmap cannot be allocated
*/
public CloseableReference<Bitmap> decodeFromPooledByteBuffer(
final CloseableReference<PooledByteBuffer> pooledByteBufferRef) {
public CloseableReference<Bitmap> decodeFromEncodedImage(final EncodedImage encodedImage) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return mArtBitmapFactory.decodeFromPooledByteBuffer(pooledByteBufferRef);
return mArtBitmapFactory.decodeFromEncodedImage(encodedImage);
} else {
return mDalvikBitmapFactory.decodeFromPooledByteBuffer(pooledByteBufferRef);
return mDalvikBitmapFactory.decodeFromEncodedImage(encodedImage);
}
}

/**
* Creates a bitmap from encoded JPEG bytes. Supports a partial JPEG image.
*
* @param pooledByteBufferRef the reference to the encoded bytes
* @param encodedImage the reference to the encoded image with the reference to the encoded bytes
* @param length the number of encoded bytes in the buffer
* @return the bitmap
* @throws TooManyBitmapsException if the pool is full
* @throws java.lang.OutOfMemoryError if the Bitmap cannot be allocated
*/
public CloseableReference<Bitmap> decodeJPEGFromPooledByteBuffer(
CloseableReference<PooledByteBuffer> pooledByteBufferRef,
public CloseableReference<Bitmap> decodeJPEGFromEncodedImage(
EncodedImage encodedImage,
int length) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return mArtBitmapFactory.decodeJPEGFromPooledByteBuffer(pooledByteBufferRef, length);
return mArtBitmapFactory.decodeJPEGFromEncodedImage(encodedImage, length);
} else {
return mDalvikBitmapFactory.decodeJPEGFromPooledByteBuffer(pooledByteBufferRef, length);
return mDalvikBitmapFactory.decodeJPEGFromEncodedImage(encodedImage, length);
}
}
}
Loading

0 comments on commit e32e0a6

Please sign in to comment.