/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.imagepipeline.producers;
import android.graphics.Rect;
import android.util.Pair;
import com.facebook.imageformat.ImageFormat;
import com.facebook.imageformat.ImageFormatChecker;
import com.facebook.imageutils.JfifUtil;
import com.facebook.common.references.CloseableReference;
import com.facebook.imagepipeline.memory.PooledByteBuffer;
import com.facebook.imagepipeline.memory.PooledByteBufferInputStream;
/**
* Add image transform meta data producer
*
* <p>Extracts meta data from the results passed down from the next producer, and adds it to the
* result that it returns to the consumer.
*/
public class AddImageTransformMetaDataProducer
implements Producer<Pair<CloseableReference<PooledByteBuffer>, ImageTransformMetaData>> {
private final Producer<CloseableReference<PooledByteBuffer>> mNextProducer;
public AddImageTransformMetaDataProducer(
Producer<CloseableReference<PooledByteBuffer>> nextProducer) {
mNextProducer = nextProducer;
}
@Override
public void produceResults(
Consumer<Pair<CloseableReference<PooledByteBuffer>, ImageTransformMetaData>> consumer,
ProducerContext context) {
mNextProducer.produceResults(new AddImageTransformMetaDataConsumer(consumer), context);
}
private class AddImageTransformMetaDataConsumer extends DelegatingConsumer<
CloseableReference<PooledByteBuffer>,
Pair<CloseableReference<PooledByteBuffer>, ImageTransformMetaData>> {
private final ImageTransformMetaData.Builder mMetaDataBuilder;
private AddImageTransformMetaDataConsumer(
Consumer<Pair<CloseableReference<PooledByteBuffer>, ImageTransformMetaData>> consumer) {
super(consumer);
mMetaDataBuilder = new ImageTransformMetaData.Builder();
}
@Override
protected void onNewResultImpl(
CloseableReference<PooledByteBuffer> newResult, boolean isLast) {
final ImageFormat imageFormat = ImageFormatChecker.getImageFormat_WrapIOException(
new PooledByteBufferInputStream(newResult.get()));
mMetaDataBuilder.reset();
mMetaDataBuilder.setImageFormat(imageFormat);
if (imageFormat == ImageFormat.JPEG && isLast) {
mMetaDataBuilder.setRotationAngle(getRotationAngle(newResult));
Rect dimensions = JfifUtil.getDimensions(new PooledByteBufferInputStream(newResult.get()));
if (dimensions != null) {
mMetaDataBuilder.setWidth(dimensions.width());
mMetaDataBuilder.setHeight(dimensions.height());
}
}
getConsumer().onNewResult(Pair.create(newResult, mMetaDataBuilder.build()), isLast);
}
// Gets the correction angle based on the image's orientation
private int getRotationAngle(final CloseableReference<PooledByteBuffer> inputRef) {
return JfifUtil.getAutoRotateAngleFromOrientation(
JfifUtil.getOrientation(new PooledByteBufferInputStream(inputRef.get())));
}
}
}