/* * 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())); } } }