/*
* 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;
/**
* 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 BaseConsumer<CloseableReference<PooledByteBuffer>> {
private final ImageTransformMetaData.Builder mMetaDataBuilder;
private final Consumer<
Pair<CloseableReference<PooledByteBuffer>, ImageTransformMetaData>> mConsumer;
private AddImageTransformMetaDataConsumer(
Consumer<Pair<CloseableReference<PooledByteBuffer>, ImageTransformMetaData>> consumer) {
mConsumer = consumer;
mMetaDataBuilder = new ImageTransformMetaData.Builder();
}
@Override
protected void onNewResultImpl(
CloseableReference<PooledByteBuffer> newResult, boolean isLast) {
final ImageFormat imageFormat =
ImageFormatChecker.getImageFormat_WrapIOException(newResult.get().getStream());
mMetaDataBuilder.reset();
mMetaDataBuilder.setImageFormat(imageFormat);
if (imageFormat == ImageFormat.JPEG && isLast) {
mMetaDataBuilder.setRotationAngle(getRotationAngle(newResult));
Rect dimensions = JfifUtil.getDimensions(newResult.get().getStream());
if (dimensions != null) {
mMetaDataBuilder.setWidth(dimensions.width());
mMetaDataBuilder.setHeight(dimensions.height());
}
}
mConsumer.onNewResult(Pair.create(newResult, mMetaDataBuilder.build()), isLast);
}
@Override
protected void onFailureImpl(Throwable t) {
mConsumer.onFailure(t);
}
@Override
protected void onCancellationImpl() {
mConsumer.onCancellation();
}
// Gets the correction angle based on the image's orientation
private int getRotationAngle(final CloseableReference<PooledByteBuffer> inputRef) {
return JfifUtil.getAutoRotateAngleFromOrientation(
JfifUtil.getOrientation(inputRef.get().getStream()));
}
}
}