10c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III/* 20c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Copyright (C) 2017 The Android Open Source Project 30c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 40c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Licensed under the Apache License, Version 2.0 (the "License"); 50c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * you may not use this file except in compliance with the License. 60c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * You may obtain a copy of the License at 70c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 80c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * http://www.apache.org/licenses/LICENSE-2.0 90c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 100c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Unless required by applicable law or agreed to in writing, software 110c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * distributed under the License is distributed on an "AS IS" BASIS, 120c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * See the License for the specific language governing permissions and 140c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * limitations under the License. 150c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 160c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 170c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins IIIpackage android.graphics; 180c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 19e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins IIIimport static android.system.OsConstants.SEEK_CUR; 20ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport static android.system.OsConstants.SEEK_SET; 21ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 225f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins IIIimport static java.lang.annotation.RetentionPolicy.SOURCE; 235f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III 240a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins IIIimport android.annotation.AnyThread; 250c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins IIIimport android.annotation.IntDef; 26d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins IIIimport android.annotation.IntRange; 270c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins IIIimport android.annotation.NonNull; 28b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins IIIimport android.annotation.Nullable; 29d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins IIIimport android.annotation.Px; 301d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins IIIimport android.annotation.TestApi; 310a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins IIIimport android.annotation.WorkerThread; 32ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport android.content.ContentResolver; 33ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport android.content.res.AssetFileDescriptor; 34121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins IIIimport android.content.res.AssetManager; 35513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins IIIimport android.content.res.AssetManager.AssetInputStream; 360c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins IIIimport android.content.res.Resources; 37671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins IIIimport android.graphics.drawable.AnimatedImageDrawable; 380c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins IIIimport android.graphics.drawable.BitmapDrawable; 39a38b2135a4bf4368734567a73d2e56f1c318fee9Leon Scroggins IIIimport android.graphics.drawable.Drawable; 400c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins IIIimport android.graphics.drawable.NinePatchDrawable; 41ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport android.net.Uri; 428290eaba47b99398fbe0bd59138f902bde558ecbLeon Scroggins IIIimport android.os.Build; 43ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport android.system.ErrnoException; 44ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport android.system.Os; 4566c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenbergerimport android.util.DisplayMetrics; 46a38b2135a4bf4368734567a73d2e56f1c318fee9Leon Scroggins IIIimport android.util.Size; 4766c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenbergerimport android.util.TypedValue; 48ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 49ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport dalvik.system.CloseGuard; 500c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 51a38b2135a4bf4368734567a73d2e56f1c318fee9Leon Scroggins IIIimport libcore.io.IoUtils; 52a38b2135a4bf4368734567a73d2e56f1c318fee9Leon Scroggins III 53e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins IIIimport java.io.File; 54ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport java.io.FileDescriptor; 55ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport java.io.FileInputStream; 56ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport java.io.FileNotFoundException; 570c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins IIIimport java.io.IOException; 580c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins IIIimport java.io.InputStream; 590c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins IIIimport java.lang.annotation.Retention; 60a38b2135a4bf4368734567a73d2e56f1c318fee9Leon Scroggins IIIimport java.nio.ByteBuffer; 61ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIimport java.util.concurrent.atomic.AtomicBoolean; 620c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 630c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III/** 64d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>A class for converting encoded images (like {@code PNG}, {@code JPEG}, 65d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@code WEBP}, {@code GIF}, or {@code HEIF}) into {@link Drawable} or 66d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link Bitmap} objects. 67d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 68d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>To use it, first create a {@link Source Source} using one of the 69d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@code createSource} overloads. For example, to decode from a {@link File}, call 70d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #createSource(File)} and pass the result to {@link #decodeDrawable(Source)} 71d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * or {@link #decodeBitmap(Source)}: 72d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 73d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <pre class="prettyprint"> 74d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * File file = new File(...); 75d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * ImageDecoder.Source source = ImageDecoder.createSource(file); 76d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Drawable drawable = ImageDecoder.decodeDrawable(source); 77d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * </pre> 78d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 79d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>To change the default settings, pass the {@link Source Source} and an 80d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener OnHeaderDecodedListener} to 81d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable(Source, OnHeaderDecodedListener)} or 82d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap(Source, OnHeaderDecodedListener)}. For example, to 83d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * create a sampled image with half the width and height of the original image, 84d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * call {@link #setTargetSampleSize setTargetSampleSize(2)} inside 85d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}: 86d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 87d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <pre class="prettyprint"> 88d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * OnHeaderDecodedListener listener = new OnHeaderDecodedListener() { 89d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * public void onHeaderDecoded(ImageDecoder decoder, ImageInfo info, Source source) { 90d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * decoder.setTargetSampleSize(2); 91d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * } 92d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * }; 93d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Drawable drawable = ImageDecoder.decodeDrawable(source, listener); 94d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * </pre> 95d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 96d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>The {@link ImageInfo ImageInfo} contains information about the encoded image, like 97d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * its width and height, and the {@link Source Source} can be used to match to a particular 98d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link Source Source} if a single {@link OnHeaderDecodedListener OnHeaderDecodedListener} 99d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * is used with multiple {@link Source Source} objects. 100d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 101d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>The {@link OnHeaderDecodedListener OnHeaderDecodedListener} can also be implemented 102d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * as a lambda: 103d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 104d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <pre class="prettyprint"> 105d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Drawable drawable = ImageDecoder.decodeDrawable(source, (decoder, info, src) -> { 106d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * decoder.setTargetSampleSize(2); 107d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * }); 108d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * </pre> 109d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 110d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>If the encoded image is an animated {@code GIF} or {@code WEBP}, 111d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable decodeDrawable} will return an {@link AnimatedImageDrawable}. To 112d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * start its animation, call {@link AnimatedImageDrawable#start AnimatedImageDrawable.start()}: 113d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 114d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <pre class="prettyprint"> 115d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Drawable drawable = ImageDecoder.decodeDrawable(source); 116d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * if (drawable instanceof AnimatedImageDrawable) { 117d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * ((AnimatedImageDrawable) drawable).start(); 118d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * } 119d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * </pre> 120d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 121d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>By default, a {@link Bitmap} created by {@link ImageDecoder} (including 122d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * one that is inside a {@link Drawable}) will be immutable (i.e. 123d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link Bitmap#isMutable Bitmap.isMutable()} returns {@code false}), and it 124d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * will typically have {@code Config} {@link Bitmap.Config#HARDWARE}. Although 125d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * these properties can be changed with {@link #setMutableRequired setMutableRequired(true)} 126d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * (which is only compatible with {@link #decodeBitmap(Source)} and 127d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap(Source, OnHeaderDecodedListener)}) and {@link #setAllocator}, 128d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * it is also possible to apply custom effects regardless of the mutability of 129d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * the final returned object by passing a {@link PostProcessor} to 130d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #setPostProcessor setPostProcessor}. A {@link PostProcessor} can also be a lambda: 131d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 132d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <pre class="prettyprint"> 133d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Drawable drawable = ImageDecoder.decodeDrawable(source, (decoder, info, src) -> { 134d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * decoder.setPostProcessor((canvas) -> { 135d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * // This will create rounded corners. 136d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Path path = new Path(); 137d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * path.setFillType(Path.FillType.INVERSE_EVEN_ODD); 138d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * int width = canvas.getWidth(); 139d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * int height = canvas.getHeight(); 140d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * path.addRoundRect(0, 0, width, height, 20, 20, Path.Direction.CW); 141d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Paint paint = new Paint(); 142d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * paint.setAntiAlias(true); 143d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * paint.setColor(Color.TRANSPARENT); 144d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); 145d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * canvas.drawPath(path, paint); 146d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * return PixelFormat.TRANSLUCENT; 147d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * }); 148d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * }); 149d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * </pre> 150d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 151d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>If the encoded image is incomplete or contains an error, or if an 152d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link Exception} occurs during decoding, a {@link DecodeException DecodeException} 153d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * will be thrown. In some cases, the {@link ImageDecoder} may have decoded part of 154d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * the image. In order to display the partial image, an 155d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnPartialImageListener OnPartialImageListener} must be passed to 156d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #setOnPartialImageListener setOnPartialImageListener}. For example: 157d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 158d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <pre class="prettyprint"> 159d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Drawable drawable = ImageDecoder.decodeDrawable(source, (decoder, info, src) -> { 160d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * decoder.setOnPartialImageListener((DecodeException e) -> { 161d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * // Returning true indicates to create a Drawable or Bitmap even 162d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * // if the whole image could not be decoded. Any remaining lines 163d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * // will be blank. 164d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * return true; 165d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * }); 166d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * }); 167d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * </pre> 1680c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 169ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins IIIpublic final class ImageDecoder implements AutoCloseable { 1708290eaba47b99398fbe0bd59138f902bde558ecbLeon Scroggins III /** @hide **/ 1718290eaba47b99398fbe0bd59138f902bde558ecbLeon Scroggins III public static int sApiLevel; 1728290eaba47b99398fbe0bd59138f902bde558ecbLeon Scroggins III 1730c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 174d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Source of encoded image data. 175d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 176d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>References the data that will be used to decode a {@link Drawable} 177d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * or {@link Bitmap} in {@link #decodeDrawable decodeDrawable} or 178d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap decodeBitmap}. Constructing a {@code Source} (with 179d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * one of the overloads of {@code createSource}) can be done on any thread 180d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * because the construction simply captures values. The real work is done 181d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * in {@link #decodeDrawable decodeDrawable} or {@link #decodeBitmap decodeBitmap}. 182d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 183d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>A {@code Source} object can be reused to create multiple versions of the 184d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * same image. For example, to decode a full size image and its thumbnail, 185d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * the same {@code Source} can be used once with no 186d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener OnHeaderDecodedListener} and once with an 187d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * implementation of {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded} 188d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * that calls {@link #setTargetSize} with smaller dimensions. One {@code Source} 1890a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * even used simultaneously in multiple threads.</p> 1900c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1910c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III public static abstract class Source { 192e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private Source() {} 193e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 1940c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /* @hide */ 195e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @Nullable 1960c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III Resources getResources() { return null; } 1970c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1980c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /* @hide */ 19966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger int getDensity() { return Bitmap.DENSITY_NONE; } 20066c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 20166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger /* @hide */ 202046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III final int computeDstDensity() { 20366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger Resources res = getResources(); 20466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger if (res == null) { 20566c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger return Bitmap.getDefaultDensity(); 20666c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 20766c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 20866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger return res.getDisplayMetrics().densityDpi; 20966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 21066c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 21166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger /* @hide */ 212e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 213ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III abstract ImageDecoder createImageDecoder() throws IOException; 2140c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III }; 2150c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 2160c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III private static class ByteArraySource extends Source { 217e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III ByteArraySource(@NonNull byte[] data, int offset, int length) { 2180c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mData = data; 2190c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mOffset = offset; 2200c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mLength = length; 2210c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III }; 2220c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III private final byte[] mData; 2230c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III private final int mOffset; 2240c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III private final int mLength; 2250c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 2260c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III @Override 227ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III public ImageDecoder createImageDecoder() throws IOException { 2281d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return nCreate(mData, mOffset, mLength, this); 2290c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 2300c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 2310c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 2320c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III private static class ByteBufferSource extends Source { 233e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III ByteBufferSource(@NonNull ByteBuffer buffer) { 2340c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mBuffer = buffer; 2350c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 2360c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III private final ByteBuffer mBuffer; 2370c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 2380c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III @Override 239ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III public ImageDecoder createImageDecoder() throws IOException { 2400c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (!mBuffer.isDirect() && mBuffer.hasArray()) { 2410c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III int offset = mBuffer.arrayOffset() + mBuffer.position(); 2420c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III int length = mBuffer.limit() - mBuffer.position(); 2431d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return nCreate(mBuffer.array(), offset, length, this); 2440c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 2450a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III ByteBuffer buffer = mBuffer.slice(); 2460a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III return nCreate(buffer, buffer.position(), buffer.limit(), this); 2470c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 2480c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 2490c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 250ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private static class ContentResolverSource extends Source { 251046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III ContentResolverSource(@NonNull ContentResolver resolver, @NonNull Uri uri, 252046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III @Nullable Resources res) { 253ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III mResolver = resolver; 254ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III mUri = uri; 255046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III mResources = res; 256ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 257ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 258ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private final ContentResolver mResolver; 259ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private final Uri mUri; 260046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III private final Resources mResources; 261046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III 262046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III @Nullable 263046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III Resources getResources() { return mResources; } 264ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 265ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III @Override 266ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III public ImageDecoder createImageDecoder() throws IOException { 267ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III AssetFileDescriptor assetFd = null; 2680c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III try { 269ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III if (mUri.getScheme() == ContentResolver.SCHEME_CONTENT) { 270ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III assetFd = mResolver.openTypedAssetFileDescriptor(mUri, 271ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III "image/*", null); 272ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } else { 273ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III assetFd = mResolver.openAssetFileDescriptor(mUri, "r"); 274ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 275ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } catch (FileNotFoundException e) { 276ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III // Some images cannot be opened as AssetFileDescriptors (e.g. 277ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III // bmp, ico). Open them as InputStreams. 278ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III InputStream is = mResolver.openInputStream(mUri); 279ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III if (is == null) { 280ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III throw new FileNotFoundException(mUri.toString()); 281ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 282ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 2831d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return createFromStream(is, true, this); 284ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 285ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 286ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III final FileDescriptor fd = assetFd.getFileDescriptor(); 287ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III final long offset = assetFd.getStartOffset(); 288ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 289ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III ImageDecoder decoder = null; 290ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III try { 291ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III try { 292ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III Os.lseek(fd, offset, SEEK_SET); 2931d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III decoder = nCreate(fd, this); 294ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } catch (ErrnoException e) { 2951d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III decoder = createFromStream(new FileInputStream(fd), true, this); 296ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 2970c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } finally { 298ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III if (decoder == null) { 299ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III IoUtils.closeQuietly(assetFd); 300ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } else { 301ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III decoder.mAssetFd = assetFd; 3020c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 3030c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 304ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III return decoder; 305ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 306ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 307ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 308e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 3091d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III private static ImageDecoder createFromFile(@NonNull File file, 3101d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III @NonNull Source source) throws IOException { 311e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III FileInputStream stream = new FileInputStream(file); 312e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III FileDescriptor fd = stream.getFD(); 313e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III try { 314e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III Os.lseek(fd, 0, SEEK_CUR); 315e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } catch (ErrnoException e) { 3161d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return createFromStream(stream, true, source); 317e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 318e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 319e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III ImageDecoder decoder = null; 320e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III try { 3211d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III decoder = nCreate(fd, source); 322e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } finally { 323e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III if (decoder == null) { 324e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III IoUtils.closeQuietly(stream); 325e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } else { 326e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III decoder.mInputStream = stream; 3270b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III decoder.mOwnsInputStream = true; 328e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 329e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 330e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III return decoder; 331e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 332e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 333e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 3340b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III private static ImageDecoder createFromStream(@NonNull InputStream is, 3351d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III boolean closeInputStream, Source source) throws IOException { 336ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III // Arbitrary size matches BitmapFactory. 337ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III byte[] storage = new byte[16 * 1024]; 338ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III ImageDecoder decoder = null; 339ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III try { 3401d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III decoder = nCreate(is, storage, source); 341ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } finally { 342ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III if (decoder == null) { 3430b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III if (closeInputStream) { 3440b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III IoUtils.closeQuietly(is); 3450b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III } 346ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } else { 347ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III decoder.mInputStream = is; 3480b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III decoder.mOwnsInputStream = closeInputStream; 349ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III decoder.mTempStorage = storage; 350ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 351ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 352ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 353ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III return decoder; 354ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 3550c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 3560b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III /** 3570b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III * For backwards compatibility, this does *not* close the InputStream. 3580a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 3590a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * Further, unlike other Sources, this one is not reusable. 3600b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III */ 36166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger private static class InputStreamSource extends Source { 36266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger InputStreamSource(Resources res, InputStream is, int inputDensity) { 36366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger if (is == null) { 36466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger throw new IllegalArgumentException("The InputStream cannot be null"); 36566c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 36666c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger mResources = res; 36766c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger mInputStream = is; 36866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger mInputDensity = res != null ? inputDensity : Bitmap.DENSITY_NONE; 36966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 37066c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 37166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger final Resources mResources; 37266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger InputStream mInputStream; 37366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger final int mInputDensity; 37466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 37566c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger @Override 37666c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger public Resources getResources() { return mResources; } 37766c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 37866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger @Override 37966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger public int getDensity() { return mInputDensity; } 38066c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 38166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger @Override 38266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger public ImageDecoder createImageDecoder() throws IOException { 38366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 38466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger synchronized (this) { 38566c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger if (mInputStream == null) { 38666c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger throw new IOException("Cannot reuse InputStreamSource"); 38766c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 38866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger InputStream is = mInputStream; 38966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger mInputStream = null; 3901d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return createFromStream(is, false, this); 39166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 39266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 39366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 39466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 395513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III /** 396513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III * Takes ownership of the AssetInputStream. 397513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III * 398513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III * @hide 399513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III */ 400513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III public static class AssetInputStreamSource extends Source { 401513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III public AssetInputStreamSource(@NonNull AssetInputStream ais, 402513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III @NonNull Resources res, @NonNull TypedValue value) { 403513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III mAssetInputStream = ais; 404513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III mResources = res; 405513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III 406513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III if (value.density == TypedValue.DENSITY_DEFAULT) { 407513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III mDensity = DisplayMetrics.DENSITY_DEFAULT; 408513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III } else if (value.density != TypedValue.DENSITY_NONE) { 409513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III mDensity = value.density; 410513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III } else { 411513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III mDensity = Bitmap.DENSITY_NONE; 412513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III } 413513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III } 414513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III 415513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III private AssetInputStream mAssetInputStream; 416513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III private final Resources mResources; 417513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III private final int mDensity; 418513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III 419513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III @Override 420513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III public Resources getResources() { return mResources; } 421513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III 422513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III @Override 423513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III public int getDensity() { 424513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III return mDensity; 425513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III } 426513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III 427513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III @Override 428513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III public ImageDecoder createImageDecoder() throws IOException { 429513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III synchronized (this) { 430513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III if (mAssetInputStream == null) { 431513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III throw new IOException("Cannot reuse AssetInputStreamSource"); 432513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III } 433513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III AssetInputStream ais = mAssetInputStream; 434513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III mAssetInputStream = null; 4351d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return createFromAsset(ais, this); 436513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III } 437513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III } 438513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III } 439513031d15b78579e39d59b71ab5a1b0afabc5544Leon Scroggins III 440ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private static class ResourceSource extends Source { 441e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III ResourceSource(@NonNull Resources res, int resId) { 4420c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mResources = res; 4430c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mResId = resId; 44466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger mResDensity = Bitmap.DENSITY_NONE; 4450c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 4460c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 4470c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III final Resources mResources; 4480c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III final int mResId; 44966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger int mResDensity; 4500a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III private Object mLock = new Object(); 4510c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 4520c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III @Override 4530c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III public Resources getResources() { return mResources; } 4540c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 4550c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III @Override 4560a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III public int getDensity() { 4570a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III synchronized (mLock) { 4580a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III return mResDensity; 4590a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III } 4600a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III } 46166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 46266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger @Override 463ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III public ImageDecoder createImageDecoder() throws IOException { 46466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger TypedValue value = new TypedValue(); 465121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III // This is just used in order to access the underlying Asset and 466121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III // keep it alive. 467121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III InputStream is = mResources.openRawResource(mResId, value); 46866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 4690a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III synchronized (mLock) { 4700a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III if (value.density == TypedValue.DENSITY_DEFAULT) { 4710a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III mResDensity = DisplayMetrics.DENSITY_DEFAULT; 4720a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III } else if (value.density != TypedValue.DENSITY_NONE) { 4730a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III mResDensity = value.density; 4740a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III } 475121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III } 47666c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 4771d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return createFromAsset((AssetInputStream) is, this); 478121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III } 479121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III } 480121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III 481121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III /** 482121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III * ImageDecoder will own the AssetInputStream. 483121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III */ 4841d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III private static ImageDecoder createFromAsset(AssetInputStream ais, 4851d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III Source source) throws IOException { 486121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III ImageDecoder decoder = null; 487121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III try { 488121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III long asset = ais.getNativeAsset(); 4891d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III decoder = nCreate(asset, source); 490121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III } finally { 491121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III if (decoder == null) { 492121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III IoUtils.closeQuietly(ais); 493121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III } else { 494121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III decoder.mInputStream = ais; 495121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III decoder.mOwnsInputStream = true; 4960c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 497121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III } 498121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III return decoder; 499121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III } 500121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III 501121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III private static class AssetSource extends Source { 502121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III AssetSource(@NonNull AssetManager assets, @NonNull String fileName) { 503121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III mAssets = assets; 504121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III mFileName = fileName; 505121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III } 506121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III 507121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III private final AssetManager mAssets; 508121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III private final String mFileName; 509121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III 510121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III @Override 511121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III public ImageDecoder createImageDecoder() throws IOException { 512121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III InputStream is = mAssets.open(mFileName); 5131d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return createFromAsset((AssetInputStream) is, this); 5140c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 5150c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 5160c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 517e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private static class FileSource extends Source { 518e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III FileSource(@NonNull File file) { 519e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III mFile = file; 520e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 521e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 522e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private final File mFile; 523e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 524e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @Override 525e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public ImageDecoder createImageDecoder() throws IOException { 5261d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return createFromFile(mFile, this); 527e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 528e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 529e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 5300c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 531d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Information about an encoded image. 5320c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 5330c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III public static class ImageInfo { 534e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private final Size mSize; 535e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private ImageDecoder mDecoder; 536e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 537e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private ImageInfo(@NonNull ImageDecoder decoder) { 538e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III mSize = new Size(decoder.mWidth, decoder.mHeight); 539e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III mDecoder = decoder; 540e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 5411fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III 5421fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III /** 543e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * Size of the image, without scaling or cropping. 5441fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III */ 545e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 546e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public Size getSize() { 547e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III return mSize; 5481fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III } 5491fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III 5501fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III /** 551e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * The mimeType of the image. 5521fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III */ 553e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 5541fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III public String getMimeType() { 555e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III return mDecoder.getMimeType(); 5560c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 557127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III 558127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III /** 559127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III * Whether the image is animated. 560127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III * 561d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>If {@code true}, {@link #decodeDrawable decodeDrawable} will 562d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * return an {@link AnimatedImageDrawable}.</p> 563127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III */ 564127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III public boolean isAnimated() { 565127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III return mDecoder.mAnimated; 566127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III } 5671a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III 5681a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III /** 5691a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * If known, the color space the decoded bitmap will have. Note that the 5701a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * output color space is not guaranteed to be the color space the bitmap 5711a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * is encoded with. If not known (when the config is 5721a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * {@link Bitmap.Config#ALPHA_8} for instance), or there is an error, 5731a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * it is set to null. 5741a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III */ 5751a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III @Nullable 5761a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III public ColorSpace getColorSpace() { 5771a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III return mDecoder.getColorSpace(); 5781a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III } 5790c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III }; 5800c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 5811d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III /** @removed 5821d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III * @deprecated Subsumed by {@link #DecodeException}. 5830c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 584ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 585ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III public static class IncompleteException extends IOException {}; 5860c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 5870c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 588d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Interface for changing the default settings of a decode. 589d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 590d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>Supply an instance to 591d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable(Source, OnHeaderDecodedListener) decodeDrawable} 592d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * or {@link #decodeBitmap(Source, OnHeaderDecodedListener) decodeBitmap}, 593d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * which will call {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded} 594d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * (in the same thread) once the size is known. The implementation of 595d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded} can then 596d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * change the decode settings as desired. 5970c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 5980c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III public static interface OnHeaderDecodedListener { 5990c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 600d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Called by {@link ImageDecoder} when the header has been decoded and 601d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * the image size is known. 6020c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 603d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @param decoder the object performing the decode, for changing 604d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * its default settings. 605d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @param info information about the encoded image. 606d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @param source object that created {@code decoder}. 6070c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 608e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public void onHeaderDecoded(@NonNull ImageDecoder decoder, 609e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull ImageInfo info, @NonNull Source source); 6100c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 6110c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III }; 6120c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 613cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III /** @removed 614cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III * @deprecated Replaced by {@link #DecodeException#SOURCE_EXCEPTION}. 615e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III */ 616ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 617e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public static final int ERROR_SOURCE_EXCEPTION = 1; 618e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 619cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III /** @removed 620cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III * @deprecated Replaced by {@link #DecodeException#SOURCE_INCOMPLETE}. 621e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III */ 622ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 623e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public static final int ERROR_SOURCE_INCOMPLETE = 2; 624e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 625cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III /** @removed 626cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III * @deprecated Replaced by {@link #DecodeException#SOURCE_MALFORMED_DATA}. 627e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III */ 628ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 629e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public static final int ERROR_SOURCE_ERROR = 3; 630e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 631e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III /** 6321d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III * Information about an interrupted decode. 6331d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III */ 6341d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III public static final class DecodeException extends IOException { 635cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III /** 636cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III * An Exception was thrown reading the {@link Source}. 637cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III */ 638cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III public static final int SOURCE_EXCEPTION = 1; 639cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III 640cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III /** 641cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III * The encoded data was incomplete. 642cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III */ 643cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III public static final int SOURCE_INCOMPLETE = 2; 644cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III 645cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III /** 646cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III * The encoded data contained an error. 647cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III */ 648cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III public static final int SOURCE_MALFORMED_DATA = 3; 649cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III 650cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III /** @hide **/ 651cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III @Retention(SOURCE) 652cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III @IntDef(value = { SOURCE_EXCEPTION, SOURCE_INCOMPLETE, SOURCE_MALFORMED_DATA }, 653cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III prefix = {"SOURCE_"}) 654cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III public @interface Error {}; 655cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III 6561d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III @Error final int mError; 6571d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III @NonNull final Source mSource; 6581d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III 6591d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III DecodeException(@Error int error, @Nullable Throwable cause, @NonNull Source source) { 6601d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III super(errorMessage(error, cause), cause); 6611d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III mError = error; 6621d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III mSource = source; 6631d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III } 6641d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III 6651d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III /** 6661d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III * Private method called by JNI. 6671d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III */ 6681d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III @SuppressWarnings("unused") 6691d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III DecodeException(@Error int error, @Nullable String msg, @Nullable Throwable cause, 6701d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III @NonNull Source source) { 6711d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III super(msg + errorMessage(error, cause), cause); 6721d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III mError = error; 6731d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III mSource = source; 6741d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III } 6751d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III 6761d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III /** 6771d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III * Retrieve the reason that decoding was interrupted. 6781d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III * 679cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III * <p>If the error is {@link #SOURCE_EXCEPTION}, the underlying 6801d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III * {@link java.lang.Throwable} can be retrieved with 6811d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III * {@link java.lang.Throwable#getCause}.</p> 6821d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III */ 6831d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III @Error 6841d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III public int getError() { 6851d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return mError; 6861d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III } 6871d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III 6881d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III /** 689d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Retrieve the {@link Source Source} that was interrupted. 6900a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 6910a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>This can be used for equality checking to find the Source which 6920a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * failed to completely decode.</p> 6931d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III */ 6941d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III @NonNull 6951d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III public Source getSource() { 6961d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return mSource; 6971d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III } 6981d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III 6991d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III private static String errorMessage(@Error int error, @Nullable Throwable cause) { 7001d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III switch (error) { 701cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III case SOURCE_EXCEPTION: 7021d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return "Exception in input: " + cause; 703cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III case SOURCE_INCOMPLETE: 7041d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return "Input was incomplete."; 705cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III case SOURCE_MALFORMED_DATA: 7061d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return "Input contained an error."; 7071d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III default: 7081d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return ""; 7091d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III } 7101d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III } 7111d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III } 7121d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III 7131d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III /** 714d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Interface for inspecting a {@link DecodeException DecodeException} 715d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * and potentially preventing it from being thrown. 716d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 717d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>If an instance is passed to 718d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #setOnPartialImageListener setOnPartialImageListener}, a 719d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link DecodeException DecodeException} that would otherwise have been 720d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * thrown can be inspected inside 721d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnPartialImageListener#onPartialImage onPartialImage}. 722d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * If {@link OnPartialImageListener#onPartialImage onPartialImage} returns 723d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@code true}, a partial image will be created. 7240c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 725edf26d6e40f0723e70d7dcd147a2a2ce07c7c1ccLeon Scroggins III public static interface OnPartialImageListener { 7260c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 727d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Called by {@link ImageDecoder} when there is only a partial image to 728d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * display. 7290c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 730d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>If decoding is interrupted after having decoded a partial image, 731d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * this method will be called. The implementation can inspect the 732d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link DecodeException DecodeException} and optionally finish the 733d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * rest of the decode creation process to create a partial {@link Drawable} 734d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * or {@link Bitmap}. 735edf26d6e40f0723e70d7dcd147a2a2ce07c7c1ccLeon Scroggins III * 736d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @param exception exception containing information about the 737d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * decode interruption. 738d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @return {@code true} to create and return a {@link Drawable} or 739d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link Bitmap} with partial data. {@code false} (which is the 740d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * default) to abort the decode and throw {@code e}. Any undecoded 741d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * lines in the image will be blank. 7420c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 743d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III boolean onPartialImage(@NonNull DecodeException exception); 7440c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III }; 7450c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 7460c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III // Fields 747671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III private long mNativePtr; 748671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III private final int mWidth; 749671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III private final int mHeight; 750671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III private final boolean mAnimated; 7517d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III private final boolean mIsNinePatch; 7520c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 7531a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private int mDesiredWidth; 7541a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private int mDesiredHeight; 7551a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private int mAllocator = ALLOCATOR_DEFAULT; 756d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III private boolean mUnpremultipliedRequired = false; 7571a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private boolean mMutable = false; 7581a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private boolean mConserveMemory = false; 7591a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private boolean mDecodeAsAlphaMask = false; 7601a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private ColorSpace mDesiredColorSpace = null; 7611a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private Rect mCropRect; 7621a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private Rect mOutPaddingRect; 7631a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private Source mSource; 7640c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 765e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private PostProcessor mPostProcessor; 766edf26d6e40f0723e70d7dcd147a2a2ce07c7c1ccLeon Scroggins III private OnPartialImageListener mOnPartialImageListener; 7670c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 768ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III // Objects for interacting with the input. 769ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private InputStream mInputStream; 7700b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III private boolean mOwnsInputStream; 771ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private byte[] mTempStorage; 772ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private AssetFileDescriptor mAssetFd; 773ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private final AtomicBoolean mClosed = new AtomicBoolean(); 774ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private final CloseGuard mCloseGuard = CloseGuard.get(); 7750c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 7760c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 777ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III * Private constructor called by JNI. {@link #close} must be 7780c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * called after decoding to delete native resources. 7790c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 7800c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III @SuppressWarnings("unused") 781671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III private ImageDecoder(long nativePtr, int width, int height, 7827d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III boolean animated, boolean isNinePatch) { 7830c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mNativePtr = nativePtr; 7840c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mWidth = width; 7850c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mHeight = height; 7860c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mDesiredWidth = width; 7870c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mDesiredHeight = height; 788671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III mAnimated = animated; 7897d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III mIsNinePatch = isNinePatch; 790ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III mCloseGuard.open("close"); 791ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 792ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 793ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III @Override 794ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III protected void finalize() throws Throwable { 795ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III try { 796ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III if (mCloseGuard != null) { 797ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III mCloseGuard.warnIfOpen(); 798ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 799ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 800127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III // Avoid closing these in finalizer. 801127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III mInputStream = null; 802127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III mAssetFd = null; 803127d31a6842b6cca49885c3607e7ea35b1885b6fLeon Scroggins III 804ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III close(); 805ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } finally { 806ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III super.finalize(); 807ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 8080c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 8090c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 8100c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 811d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Create a new {@link Source Source} from a resource. 8120c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 8130c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @param res the {@link Resources} object containing the image data. 8140c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @param resId resource ID of the image data. 8150c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @return a new Source object, which can be passed to 816d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable decodeDrawable} or 817d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap decodeBitmap}. 8180c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 8190a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 820ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III @NonNull 8211eccac89c13a79671e04cfce359a9506b284d5feLeon Scroggins III public static Source createSource(@NonNull Resources res, int resId) 822ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III { 8230c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III return new ResourceSource(res, resId); 8240c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 8250c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 8260c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 827d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Create a new {@link Source Source} from a {@link android.net.Uri}. 828d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 829d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <h5>Accepts the following URI schemes:</h5> 830d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <ul> 831d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <li>content ({@link ContentResolver#SCHEME_CONTENT})</li> 832d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <li>android.resource ({@link ContentResolver#SCHEME_ANDROID_RESOURCE})</li> 833d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <li>file ({@link ContentResolver#SCHEME_FILE})</li> 834d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * </ul> 835ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III * 836ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III * @param cr to retrieve from. 837ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III * @param uri of the image file. 838ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III * @return a new Source object, which can be passed to 839d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable decodeDrawable} or 840d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap decodeBitmap}. 841ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III */ 8420a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 843ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III @NonNull 844ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III public static Source createSource(@NonNull ContentResolver cr, 845ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III @NonNull Uri uri) { 846046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III return new ContentResolverSource(cr, uri, null); 847046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III } 848046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III 849046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III /** 850046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III * Provide Resources for density scaling. 851046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III * 852046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III * @hide 853046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III */ 8540a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 855046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III @NonNull 856046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III public static Source createSource(@NonNull ContentResolver cr, 857046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III @NonNull Uri uri, @Nullable Resources res) { 858046a99ebbb90f9ecdead7b057ef99764a1d295b9Leon Scroggins III return new ContentResolverSource(cr, uri, res); 859ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 860ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 861ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III /** 862d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Create a new {@link Source Source} from a file in the "assets" directory. 863121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III */ 8640a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 865121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III @NonNull 866121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III public static Source createSource(@NonNull AssetManager assets, @NonNull String fileName) { 867121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III return new AssetSource(assets, fileName); 868121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III } 869121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III 870121ef98bfb0e34a2726dd0fb9112915017bfcde4Leon Scroggins III /** 871d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Create a new {@link Source Source} from a byte array. 872e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * 8730c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @param data byte array of compressed image data. 8740c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @param offset offset into data for where the decoder should begin 8750c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * parsing. 8760c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @param length number of bytes, beginning at offset, to parse. 877d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @return a new Source object, which can be passed to 878d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable decodeDrawable} or 879d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap decodeBitmap}. 8800c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @throws NullPointerException if data is null. 8810c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @throws ArrayIndexOutOfBoundsException if offset and length are 8820c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * not within data. 883e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * @hide 8840c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 8850a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 886e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 8870c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III public static Source createSource(@NonNull byte[] data, int offset, 8880c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III int length) throws ArrayIndexOutOfBoundsException { 8890c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (data == null) { 8900c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III throw new NullPointerException("null byte[] in createSource!"); 8910c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 8920c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (offset < 0 || length < 0 || offset >= data.length || 8930c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III offset + length > data.length) { 8940c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III throw new ArrayIndexOutOfBoundsException( 8950c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III "invalid offset/length!"); 8960c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 8970c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III return new ByteArraySource(data, offset, length); 8980c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 8990c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 9000c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 901b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III * See {@link #createSource(byte[], int, int). 902e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * @hide 903b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III */ 9040a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 905e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 906b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III public static Source createSource(@NonNull byte[] data) { 907b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III return createSource(data, 0, data.length); 908b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III } 909b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III 910b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III /** 911d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Create a new {@link Source Source} from a {@link java.nio.ByteBuffer}. 9120c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 913d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>Decoding will start from {@link java.nio.ByteBuffer#position() buffer.position()}. 914d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * The position of {@code buffer} will not be affected.</p> 9150c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 916d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>Note: If this {@code Source} is passed to {@link #decodeDrawable decodeDrawable}, 917d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * and the encoded image is animated, the returned {@link AnimatedImageDrawable} 9184367534058a07fd79ef1bbfec4e27f34275ab5c7Leon Scroggins III * will continue reading from the {@code buffer}, so its contents must not 9194367534058a07fd79ef1bbfec4e27f34275ab5c7Leon Scroggins III * be modified, even after the {@code AnimatedImageDrawable} is returned. 9204367534058a07fd79ef1bbfec4e27f34275ab5c7Leon Scroggins III * {@code buffer}'s contents should never be modified during decode.</p> 921d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 922d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @return a new Source object, which can be passed to 923d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable decodeDrawable} or 924d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap decodeBitmap}. 9250c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 9260a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 927e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 928e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public static Source createSource(@NonNull ByteBuffer buffer) { 9290a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III return new ByteBufferSource(buffer); 9300c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 9310c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 9320c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 93366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger * Internal API used to generate bitmaps for use by Drawables (i.e. BitmapDrawable) 9340a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 9350a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Unlike other Sources, this one cannot be reused.</p> 9360a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 93766c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger * @hide 93866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger */ 9390a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 9400a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @NonNull 94166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger public static Source createSource(Resources res, InputStream is) { 94266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger return new InputStreamSource(res, is, Bitmap.getDefaultDensity()); 94366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 94466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 94566c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger /** 94666c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger * Internal API used to generate bitmaps for use by Drawables (i.e. BitmapDrawable) 9470a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 9480a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Unlike other Sources, this one cannot be reused.</p> 9490a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 95066c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger * @hide 95166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger */ 9520a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 9531d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III @TestApi 9540a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @NonNull 95566c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger public static Source createSource(Resources res, InputStream is, int density) { 95666c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger return new InputStreamSource(res, is, density); 95766c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 95866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 95966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger /** 960d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Create a new {@link Source Source} from a {@link java.io.File}. 961d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 962d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @return a new Source object, which can be passed to 963d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable decodeDrawable} or 964d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap decodeBitmap}. 965e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III */ 9660a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @AnyThread 967e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 968e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public static Source createSource(@NonNull File file) { 969e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III return new FileSource(file); 970e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 971e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 972e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III /** 9730c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Return the width and height of a given sample size. 9740c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 975e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * <p>This takes an input that functions like 9760c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * {@link BitmapFactory.Options#inSampleSize}. It returns a width and 97764481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * height that can be achieved by sampling the encoded image. Other widths 9780c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * and heights may be supported, but will require an additional (internal) 9790c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * scaling step. Such internal scaling is *not* supported with 980d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * {@link #setUnpremultipliedRequired} set to {@code true}.</p> 9810c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 9820c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @param sampleSize Sampling rate of the encoded image. 983e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * @return {@link android.util.Size} of the width and height after 984e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * sampling. 98564481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * 98664481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * @hide 9870c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 988e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 989e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public Size getSampledSize(int sampleSize) { 9900c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (sampleSize <= 0) { 9910c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III throw new IllegalArgumentException("sampleSize must be positive! " 9920c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III + "provided " + sampleSize); 9930c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 9940c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (mNativePtr == 0) { 995ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III throw new IllegalStateException("ImageDecoder is closed!"); 9960c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 9970c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 9980c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III return nGetSampledSize(mNativePtr, sampleSize); 9990c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 10000c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 10010c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III // Modifiers 100264481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III /** @removed 100364481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * @deprecated Renamed to {@link #setTargetSize}. 100464481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III */ 1005ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 100664481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III public ImageDecoder setResize(int width, int height) { 1007d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III this.setTargetSize(width, height); 1008d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III return this; 100964481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III } 101064481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III 10110c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 101264481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * Specify the size of the output {@link Drawable} or {@link Bitmap}. 101364481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * 101464481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * <p>By default, the output size will match the size of the encoded 1015d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * image, which can be retrieved from the {@link ImageInfo ImageInfo} in 1016d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 1017d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 1018d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>This will sample or scale the output to an arbitrary size that may 1019d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * be smaller or larger than the encoded size.</p> 102064481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * 10211a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * <p>Only the last call to this or {@link #setTargetSampleSize} is 10221a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * respected.</p> 10230c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 10240a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1025d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 10260a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 1027d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III * @param width width in pixels of the output, must be greater than 0 1028d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III * @param height height in pixels of the output, must be greater than 0 10290c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1030d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III public void setTargetSize(@Px @IntRange(from = 1) int width, 1031d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III @Px @IntRange(from = 1) int height) { 10320c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (width <= 0 || height <= 0) { 10330c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III throw new IllegalArgumentException("Dimensions must be positive! " 10340c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III + "provided (" + width + ", " + height + ")"); 10350c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 10360c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 10370c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mDesiredWidth = width; 10380c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mDesiredHeight = height; 10390c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 10400c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 104164481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III /** @removed 10421a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * @deprecated Renamed to {@link #setTargetSampleSize}. 104364481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III */ 1044ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 104564481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III public ImageDecoder setResize(int sampleSize) { 1046d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III this.setTargetSampleSize(sampleSize); 1047d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III return this; 104864481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III } 104964481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III 105064481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III private int getTargetDimension(int original, int sampleSize, int computed) { 105164481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III // Sampling will never result in a smaller size than 1. 105264481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III if (sampleSize >= original) { 105364481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III return 1; 105464481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III } 105564481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III 105664481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III // Use integer divide to find the desired size. If that is what 105764481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III // getSampledSize computed, that is the size to use. 105864481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III int target = original / sampleSize; 105964481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III if (computed == target) { 106064481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III return computed; 106164481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III } 106264481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III 106364481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III // If sampleSize does not divide evenly into original, the decoder 106464481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III // may round in either direction. It just needs to get a result that 106564481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III // is close. 106664481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III int reverse = computed * sampleSize; 106764481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III if (Math.abs(reverse - original) < sampleSize) { 106864481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III // This is the size that can be decoded most efficiently. 106964481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III return computed; 107064481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III } 107164481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III 107264481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III // The decoder could not get close (e.g. it is a DNG image). 107364481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III return target; 107464481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III } 107564481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III 10760c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 107764481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * Set the target size with a sampleSize. 107864481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * 107964481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * <p>By default, the output size will match the size of the encoded 1080d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * image, which can be retrieved from the {@link ImageInfo ImageInfo} in 1081d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 10820c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 108364481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * <p>Requests the decoder to subsample the original image, returning a 1084d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * smaller image to save memory. The {@code sampleSize} is the number of pixels 108564481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * in either dimension that correspond to a single pixel in the output. 1086d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * For example, {@code sampleSize == 4} returns an image that is 1/4 the 108764481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * width/height of the original, and 1/16 the number of pixels.</p> 108864481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * 108964481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * <p>Must be greater than or equal to 1.</p> 109064481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * 1091d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III * <p>This has the same effect as calling {@link #setTargetSize} with 1092d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III * dimensions based on the {@code sampleSize}. Unlike dividing the original 1093d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III * width and height by the {@code sampleSize} manually, calling this method 1094d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III * allows {@code ImageDecoder} to round in the direction that it can do most 1095d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III * efficiently.</p> 1096d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III * 109764481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * <p>Only the last call to this or {@link #setTargetSize} is respected.</p> 10980c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 10990a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1100d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 11010a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 1102d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III * @param sampleSize sampling rate of the encoded image. 11030c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1104d97e26428d1c61759910a1b983d5e316c9b893a1Leon Scroggins III public void setTargetSampleSize(@IntRange(from = 1) int sampleSize) { 1105e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III Size size = this.getSampledSize(sampleSize); 110664481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III int targetWidth = getTargetDimension(mWidth, sampleSize, size.getWidth()); 110764481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III int targetHeight = getTargetDimension(mHeight, sampleSize, size.getHeight()); 1108d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III this.setTargetSize(targetWidth, targetHeight); 11090c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 11100c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 111166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger private boolean requestedResize() { 111266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger return mWidth != mDesiredWidth || mHeight != mDesiredHeight; 111366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 111466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 11150c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III // These need to stay in sync with ImageDecoder.cpp's Allocator enum. 11160c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 11170c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Use the default allocation for the pixel memory. 11180c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 11190c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Will typically result in a {@link Bitmap.Config#HARDWARE} 11200c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * allocation, but may be software for small images. In addition, this will 11210c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * switch to software when HARDWARE is incompatible, e.g. 1122d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #setMutableRequired setMutableRequired(true)} or 1123d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #setDecodeAsAlphaMaskEnabled setDecodeAsAlphaMaskEnabled(true)}. 11240c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1125e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public static final int ALLOCATOR_DEFAULT = 0; 11260c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 11270c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 11280c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Use a software allocation for the pixel memory. 11290c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1130ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * <p>Useful for drawing to a software {@link Canvas} or for 11310c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * accessing the pixels on the final output. 11320c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1133e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public static final int ALLOCATOR_SOFTWARE = 1; 11340c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 11350c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 11360c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Use shared memory for the pixel memory. 11370c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1138ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * <p>Useful for sharing across processes. 11390c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1140e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public static final int ALLOCATOR_SHARED_MEMORY = 2; 11410c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 11420c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 11430c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Require a {@link Bitmap.Config#HARDWARE} {@link Bitmap}. 11440c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1145ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * <p>When this is combined with incompatible options, like 1146d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #setMutableRequired setMutableRequired(true)} or 1147d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #setDecodeAsAlphaMaskEnabled setDecodeAsAlphaMaskEnabled(true)}, 1148d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable decodeDrawable} or {@link #decodeBitmap decodeBitmap} 1149d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * will throw an {@link java.lang.IllegalStateException}. 11500c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1151e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III public static final int ALLOCATOR_HARDWARE = 3; 11520c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 11530c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** @hide **/ 11540c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III @Retention(SOURCE) 115562f0800ef4f41f97ddb18b755a63c01fea67b9faLeon Scroggins III @IntDef(value = { ALLOCATOR_DEFAULT, ALLOCATOR_SOFTWARE, 115662f0800ef4f41f97ddb18b755a63c01fea67b9faLeon Scroggins III ALLOCATOR_SHARED_MEMORY, ALLOCATOR_HARDWARE }, 115762f0800ef4f41f97ddb18b755a63c01fea67b9faLeon Scroggins III prefix = {"ALLOCATOR_"}) 11580c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III public @interface Allocator {}; 11590c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 11600c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 11610c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Choose the backing for the pixel memory. 11620c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 11630a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>This is ignored for animated drawables.</p> 11640a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 11650a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1166d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 11670c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 11680c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * @param allocator Type of allocator to use. 11690c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1170d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III public void setAllocator(@Allocator int allocator) { 1171e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III if (allocator < ALLOCATOR_DEFAULT || allocator > ALLOCATOR_HARDWARE) { 11720c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III throw new IllegalArgumentException("invalid allocator " + allocator); 11730c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 11740c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mAllocator = allocator; 11750c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 11760c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 11770c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 1178746a9fee937969af9be7e060335e26e098971615Leon Scroggins III * Return the allocator for the pixel memory. 1179746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1180746a9fee937969af9be7e060335e26e098971615Leon Scroggins III @Allocator 1181746a9fee937969af9be7e060335e26e098971615Leon Scroggins III public int getAllocator() { 1182746a9fee937969af9be7e060335e26e098971615Leon Scroggins III return mAllocator; 1183746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1184746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 1185746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** 1186e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * Specify whether the {@link Bitmap} should have unpremultiplied pixels. 11870c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 11885f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III * <p>By default, ImageDecoder will create a {@link Bitmap} with 11890c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * premultiplied pixels, which is required for drawing with the 11900c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * {@link android.view.View} system (i.e. to a {@link Canvas}). Calling 1191e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * this method with a value of {@code true} will result in 1192e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * {@link #decodeBitmap} returning a {@link Bitmap} with unpremultiplied 1193d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * pixels. See {@link Bitmap#isPremultiplied Bitmap.isPremultiplied()}. 1194d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * This is incompatible with {@link #decodeDrawable decodeDrawable}; 1195d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * attempting to decode an unpremultiplied {@link Drawable} will throw an 1196d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link java.lang.IllegalStateException}. </p> 11975f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III * 11980a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1199d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 12000c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1201d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III public void setUnpremultipliedRequired(boolean unpremultipliedRequired) { 1202d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III mUnpremultipliedRequired = unpremultipliedRequired; 12030c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 12040c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1205d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III /** @removed 1206d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * @deprecated Renamed to {@link #setUnpremultipliedRequired}. 1207d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III */ 1208ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1209d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III public ImageDecoder setRequireUnpremultiplied(boolean unpremultipliedRequired) { 1210d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III this.setUnpremultipliedRequired(unpremultipliedRequired); 1211d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III return this; 1212d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III } 1213d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III 12140c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 1215746a9fee937969af9be7e060335e26e098971615Leon Scroggins III * Return whether the {@link Bitmap} will have unpremultiplied pixels. 1216746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1217d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III public boolean isUnpremultipliedRequired() { 1218d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III return mUnpremultipliedRequired; 1219d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III } 1220d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III 1221d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III /** @removed 1222d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * @deprecated Renamed to {@link #isUnpremultipliedRequired}. 1223d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III */ 1224ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1225746a9fee937969af9be7e060335e26e098971615Leon Scroggins III public boolean getRequireUnpremultiplied() { 1226d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III return this.isUnpremultipliedRequired(); 1227746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1228746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 1229746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** 12300c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Modify the image after decoding and scaling. 12310c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1232e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * <p>This allows adding effects prior to returning a {@link Drawable} or 12330c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * {@link Bitmap}. For a {@code Drawable} or an immutable {@code Bitmap}, 1234e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * this is the only way to process the image after decoding.</p> 12350c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1236d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>If combined with {@link #setTargetSize} and/or {@link #setCrop}, 1237d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link PostProcessor#onPostProcess} occurs last.</p> 1238d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 1239e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * <p>If set on a nine-patch image, the nine-patch data is ignored.</p> 12400c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1241e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * <p>For an animated image, the drawing commands drawn on the 1242e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * {@link Canvas} will be recorded immediately and then applied to each 1243e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * frame.</p> 12445f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III * 12450a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1246d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 12470a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 12480c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1249d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III public void setPostProcessor(@Nullable PostProcessor postProcessor) { 1250d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III mPostProcessor = postProcessor; 12510c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 12520c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 12530c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 1254746a9fee937969af9be7e060335e26e098971615Leon Scroggins III * Return the {@link PostProcessor} currently set. 1255746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1256746a9fee937969af9be7e060335e26e098971615Leon Scroggins III @Nullable 1257746a9fee937969af9be7e060335e26e098971615Leon Scroggins III public PostProcessor getPostProcessor() { 1258746a9fee937969af9be7e060335e26e098971615Leon Scroggins III return mPostProcessor; 1259746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1260746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 1261746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** 1262edf26d6e40f0723e70d7dcd147a2a2ce07c7c1ccLeon Scroggins III * Set (replace) the {@link OnPartialImageListener} on this object. 12630c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 12645f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III * <p>Will be called if there is an error in the input. Without one, an 1265d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * error will result in an {@code Exception} being thrown.</p> 12665f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III * 12670a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1268d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 12690a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 12700c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1271d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III public void setOnPartialImageListener(@Nullable OnPartialImageListener listener) { 1272d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III mOnPartialImageListener = listener; 12730c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 12740c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 12750c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 1276d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Return the {@link OnPartialImageListener OnPartialImageListener} currently set. 1277746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1278746a9fee937969af9be7e060335e26e098971615Leon Scroggins III @Nullable 1279746a9fee937969af9be7e060335e26e098971615Leon Scroggins III public OnPartialImageListener getOnPartialImageListener() { 1280746a9fee937969af9be7e060335e26e098971615Leon Scroggins III return mOnPartialImageListener; 1281746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1282746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 1283746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** 12840c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * Crop the output to {@code subset} of the (possibly) scaled image. 12850c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1286e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * <p>{@code subset} must be contained within the size set by 128764481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * {@link #setTargetSize} or the bounds of the image if setTargetSize was 128864481195e13e2dd7197fff569344e5a263b7871aLeon Scroggins III * not called. Otherwise an {@link IllegalStateException} will be thrown by 1289d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeDrawable decodeDrawable}/{@link #decodeBitmap decodeBitmap}.</p> 12900c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1291e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * <p>NOT intended as a replacement for 1292d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link BitmapRegionDecoder#decodeRegion BitmapRegionDecoder.decodeRegion()}. 1293d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * This supports all formats, but merely crops the output.</p> 12945f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III * 12950a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1296d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 12970a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 12980c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1299d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III public void setCrop(@Nullable Rect subset) { 13000c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mCropRect = subset; 13010c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 13020c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 13030c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 1304746a9fee937969af9be7e060335e26e098971615Leon Scroggins III * Return the cropping rectangle, if set. 1305746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1306746a9fee937969af9be7e060335e26e098971615Leon Scroggins III @Nullable 1307746a9fee937969af9be7e060335e26e098971615Leon Scroggins III public Rect getCrop() { 1308746a9fee937969af9be7e060335e26e098971615Leon Scroggins III return mCropRect; 1309746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1310746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 1311746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** 13122f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III * Set a Rect for retrieving nine patch padding. 13132f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III * 13142f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III * If the image is a nine patch, this Rect will be set to the padding 13152f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III * rectangle during decode. Otherwise it will not be modified. 13162f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III * 13170a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1318d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 13190a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 13202f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III * @hide 13212f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III */ 1322d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III public void setOutPaddingRect(@NonNull Rect outPadding) { 13232f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III mOutPaddingRect = outPadding; 13242f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III } 13252f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III 13262f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III /** 1327e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * Specify whether the {@link Bitmap} should be mutable. 13280c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1329d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>By default, a {@link Bitmap} created by {@link #decodeBitmap decodeBitmap} 1330d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * will be immutable i.e. {@link Bitmap#isMutable() Bitmap.isMutable()} returns 1331d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@code false}. This can be changed with {@code setMutableRequired(true)}. 13320c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1333e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * <p>Mutable Bitmaps are incompatible with {@link #ALLOCATOR_HARDWARE}, 1334e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * because {@link Bitmap.Config#HARDWARE} Bitmaps cannot be mutable. 1335e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * Attempting to combine them will throw an 1336e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * {@link java.lang.IllegalStateException}.</p> 13370c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1338d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>Mutable Bitmaps are also incompatible with {@link #decodeDrawable decodeDrawable}, 1339e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * which would require retrieving the Bitmap from the returned Drawable in 1340e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * order to modify. Attempting to decode a mutable {@link Drawable} will 1341e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * throw an {@link java.lang.IllegalStateException}.</p> 13425f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III * 13430a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1344d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 13450c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1346d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III public void setMutableRequired(boolean mutable) { 1347e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III mMutable = mutable; 13480c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 13490c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1350d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III /** @removed 1351d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * @deprecated Renamed to {@link #setMutableRequired}. 1352d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III */ 1353ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1354d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III public ImageDecoder setMutable(boolean mutable) { 1355d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III this.setMutableRequired(mutable); 1356d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III return this; 1357d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III } 1358d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III 13590c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 1360d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Return whether the decoded {@link Bitmap} will be mutable. 1361746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1362d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III public boolean isMutableRequired() { 1363746a9fee937969af9be7e060335e26e098971615Leon Scroggins III return mMutable; 1364746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1365746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 1366d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III /** @removed 1367d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * @deprecated Renamed to {@link #isMutableRequired}. 1368d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III */ 1369ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1370d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III public boolean getMutable() { 1371d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III return this.isMutableRequired(); 1372d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III } 1373d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III 1374746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** 1375ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * Save memory if possible by using a denser {@link Bitmap.Config} at the 1376ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * cost of some image quality. 13770c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1378ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * <p>For example an opaque 8-bit image may be compressed into an 1379ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * {@link Bitmap.Config#RGB_565} configuration, sacrificing image 1380ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * quality to save memory. 1381ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III */ 1382ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III public static final int MEMORY_POLICY_LOW_RAM = 0; 1383ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III 1384ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III /** 1385ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * Use the most natural {@link Bitmap.Config} for the internal {@link Bitmap}. 1386ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * 1387ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * <p>This is the recommended default for most applications and usages. This 1388ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * will use the closest {@link Bitmap.Config} for the encoded source. If the 1389ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * encoded source does not exactly match any {@link Bitmap.Config}, the next 1390ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * highest quality {@link Bitmap.Config} will be used avoiding any loss in 1391ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * image quality. 1392ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III */ 1393ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III public static final int MEMORY_POLICY_DEFAULT = 1; 1394ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III 1395ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III /** @hide **/ 1396ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Retention(SOURCE) 1397ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @IntDef(value = { MEMORY_POLICY_DEFAULT, MEMORY_POLICY_LOW_RAM }, 1398ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III prefix = {"MEMORY_POLICY_"}) 1399ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III public @interface MemoryPolicy {}; 1400ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III 1401ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III /** 1402ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * Specify the memory policy for the decoded {@link Bitmap}. 14035f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III * 14040a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1405d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 14060c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1407ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III public void setMemorySizePolicy(@MemoryPolicy int policy) { 1408ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III mConserveMemory = (policy == MEMORY_POLICY_LOW_RAM); 1409ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III } 1410ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III 1411ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III /** 1412ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * Retrieve the memory policy for the decoded {@link Bitmap}. 1413ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III */ 1414ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @MemoryPolicy 1415ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III public int getMemorySizePolicy() { 1416ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III return mConserveMemory ? MEMORY_POLICY_LOW_RAM : MEMORY_POLICY_DEFAULT; 1417ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III } 1418ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III 1419ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III /** @removed 1420ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * @deprecated Replaced by {@link #setMemorySizePolicy}. 1421ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III */ 1422ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1423d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III public void setConserveMemory(boolean conserveMemory) { 1424a38b2135a4bf4368734567a73d2e56f1c318fee9Leon Scroggins III mConserveMemory = conserveMemory; 14250c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 14260c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1427ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III /** @removed 1428ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III * @deprecated Replaced by {@link #getMemorySizePolicy}. 1429746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1430ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1431746a9fee937969af9be7e060335e26e098971615Leon Scroggins III public boolean getConserveMemory() { 1432746a9fee937969af9be7e060335e26e098971615Leon Scroggins III return mConserveMemory; 1433746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1434746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 1435746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** 1436e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * Specify whether to potentially treat the output as an alpha mask. 14370c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1438e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * <p>If this is set to {@code true} and the image is encoded in a format 1439e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * with only one channel, treat that channel as alpha. Otherwise this call has 1440e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * no effect.</p> 14410c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III * 1442d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * <p>This is incompatible with {@link #ALLOCATOR_HARDWARE}. Trying to 1443d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * combine them will result in {@link #decodeDrawable decodeDrawable}/ 1444d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap decodeBitmap} throwing an 1445e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * {@link java.lang.IllegalStateException}.</p> 14465f7e948ad808d3f9c84482594e0da45b4181a6e5Leon Scroggins III * 14470a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1448d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 14490c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 1450d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III public void setDecodeAsAlphaMaskEnabled(boolean enabled) { 1451d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III mDecodeAsAlphaMask = enabled; 14520c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 14530c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1454746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** @removed 1455d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * @deprecated Renamed to {@link #setDecodeAsAlphaMaskEnabled}. 1456d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III */ 1457ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1458d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III public ImageDecoder setDecodeAsAlphaMask(boolean enabled) { 1459d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III this.setDecodeAsAlphaMaskEnabled(enabled); 1460d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III return this; 1461d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III } 1462d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III 1463d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III /** @removed 1464d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * @deprecated Renamed to {@link #setDecodeAsAlphaMaskEnabled}. 1465746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1466ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1467746a9fee937969af9be7e060335e26e098971615Leon Scroggins III public ImageDecoder setAsAlphaMask(boolean asAlphaMask) { 1468d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III this.setDecodeAsAlphaMask(asAlphaMask); 1469d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III return this; 1470746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1471746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 1472746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** 1473746a9fee937969af9be7e060335e26e098971615Leon Scroggins III * Return whether to treat single channel input as alpha. 1474746a9fee937969af9be7e060335e26e098971615Leon Scroggins III * 1475d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * <p>This returns whether {@link #setDecodeAsAlphaMaskEnabled} was set to 1476d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * {@code true}. It may still return {@code true} even if the image has 1477d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * more than one channel and therefore will not be treated as an alpha 1478d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * mask.</p> 1479d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III */ 1480d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III public boolean isDecodeAsAlphaMaskEnabled() { 1481d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III return mDecodeAsAlphaMask; 1482d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III } 1483d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III 1484d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III /** @removed 1485d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * @deprecated Renamed to {@link #isDecodeAsAlphaMaskEnabled}. 1486746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1487ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1488746a9fee937969af9be7e060335e26e098971615Leon Scroggins III public boolean getDecodeAsAlphaMask() { 1489746a9fee937969af9be7e060335e26e098971615Leon Scroggins III return mDecodeAsAlphaMask; 1490746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1491746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 1492746a9fee937969af9be7e060335e26e098971615Leon Scroggins III /** @removed 1493d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III * @deprecated Renamed to {@link #isDecodeAsAlphaMaskEnabled}. 1494746a9fee937969af9be7e060335e26e098971615Leon Scroggins III */ 1495ac959199e5cf553a1b42a486e91918ead4394ff5Leon Scroggins III @Deprecated 1496746a9fee937969af9be7e060335e26e098971615Leon Scroggins III public boolean getAsAlphaMask() { 1497746a9fee937969af9be7e060335e26e098971615Leon Scroggins III return this.getDecodeAsAlphaMask(); 1498746a9fee937969af9be7e060335e26e098971615Leon Scroggins III } 1499746a9fee937969af9be7e060335e26e098971615Leon Scroggins III 15001a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III /** 15011a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * Specify the desired {@link ColorSpace} for the output. 15021a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * 1503d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>If non-null, the decoder will try to decode into {@code colorSpace}. 1504d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * If it is null, which is the default, or the request cannot be met, the 1505d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * decoder will pick either the color space embedded in the image or the 1506d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link ColorSpace} best suited for the requested image configuration 1507d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * (for instance {@link ColorSpace.Named#SRGB sRGB} for the 1508d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link Bitmap.Config#ARGB_8888} configuration).</p> 15091a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * 15101a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * <p>{@link Bitmap.Config#RGBA_F16} always uses the 1511d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link ColorSpace.Named#LINEAR_EXTENDED_SRGB scRGB} color space. 15121a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * Bitmaps in other configurations without an embedded color space are 15131a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * assumed to be in the {@link ColorSpace.Named#SRGB sRGB} color space.</p> 15141a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * 15151a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * <p class="note">Only {@link ColorSpace.Model#RGB} color spaces are 15161a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * currently supported. An <code>IllegalArgumentException</code> will 1517d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * be thrown by {@link #decodeDrawable decodeDrawable}/ 1518d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link #decodeBitmap decodeBitmap} when setting a non-RGB color space 15191a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * such as {@link ColorSpace.Named#CIE_LAB Lab}.</p> 15201a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * 15211a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * <p class="note">The specified color space's transfer function must be 15221a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * an {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}. An 15231a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * <code>IllegalArgumentException</code> will be thrown by the decode methods 15241a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * if calling {@link ColorSpace.Rgb#getTransferParameters()} on the 15251a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III * specified color space returns null.</p> 15260a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 15270a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * <p>Like all setters on ImageDecoder, this must be called inside 1528d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p> 15291a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III */ 1530d9b53a097d0eec2d1112b25a67b28c203e9251f9Leon Scroggins III public void setTargetColorSpace(ColorSpace colorSpace) { 15311a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III mDesiredColorSpace = colorSpace; 15321a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III } 15331a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III 1534d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III /** 1535d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * Closes this resource, relinquishing any underlying resources. This method 1536d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * is invoked automatically on objects managed by the try-with-resources 1537d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * statement. 1538d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * 1539d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>This is an implementation detail of {@link ImageDecoder}, and should 1540d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * never be called manually.</p> 1541d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III */ 1542ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III @Override 1543ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III public void close() { 1544ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III mCloseGuard.close(); 1545ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III if (!mClosed.compareAndSet(false, true)) { 15460c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III return; 15470c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 1548ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III nClose(mNativePtr); 15490c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III mNativePtr = 0; 1550ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 15510b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III if (mOwnsInputStream) { 15520b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III IoUtils.closeQuietly(mInputStream); 15530b49f5725cabd64d27960b1b017e5c009f701cf8Leon Scroggins III } 1554ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III IoUtils.closeQuietly(mAssetFd); 1555ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III 1556ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III mInputStream = null; 1557ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III mAssetFd = null; 1558ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III mTempStorage = null; 15590c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 15600c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 15610c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III private void checkState() { 15620c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (mNativePtr == 0) { 1563ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III throw new IllegalStateException("Cannot use closed ImageDecoder!"); 15640c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 15650c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 15660c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III checkSubset(mDesiredWidth, mDesiredHeight, mCropRect); 15670c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1568e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III if (mAllocator == ALLOCATOR_HARDWARE) { 15690c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (mMutable) { 15700c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III throw new IllegalStateException("Cannot make mutable HARDWARE Bitmap!"); 15710c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 1572746a9fee937969af9be7e060335e26e098971615Leon Scroggins III if (mDecodeAsAlphaMask) { 15730c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III throw new IllegalStateException("Cannot make HARDWARE Alpha mask Bitmap!"); 15740c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 15750c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 15760c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1577d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III if (mPostProcessor != null && mUnpremultipliedRequired) { 15780c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III throw new IllegalStateException("Cannot draw to unpremultiplied pixels!"); 15790c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 15801a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III 15811a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III if (mDesiredColorSpace != null) { 15821a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III if (!(mDesiredColorSpace instanceof ColorSpace.Rgb)) { 15831a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III throw new IllegalArgumentException("The target color space must use the " 15841a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III + "RGB color model - provided: " + mDesiredColorSpace); 15851a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III } 15861a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III if (((ColorSpace.Rgb) mDesiredColorSpace).getTransferParameters() == null) { 15871a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III throw new IllegalArgumentException("The target color space must use an " 15881a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III + "ICC parametric transfer function - provided: " + mDesiredColorSpace); 15891a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III } 15901a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III } 15910c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 15920c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 15930c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III private static void checkSubset(int width, int height, Rect r) { 15940c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (r == null) { 15950c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III return; 15960c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 15970c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (r.left < 0 || r.top < 0 || r.right > width || r.bottom > height) { 15980c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III throw new IllegalStateException("Subset " + r + " not contained by " 15990c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III + "scaled image bounds: (" + width + " x " + height + ")"); 16000c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 16010c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 16020c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 16030a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @WorkerThread 1604e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 1605c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III private Bitmap decodeBitmapInternal() throws IOException { 16068c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III checkState(); 16071d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III return nDecodeBitmap(mNativePtr, this, mPostProcessor != null, 16081d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III mDesiredWidth, mDesiredHeight, mCropRect, 1609d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III mMutable, mAllocator, mUnpremultipliedRequired, 16101a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III mConserveMemory, mDecodeAsAlphaMask, mDesiredColorSpace); 16118c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III } 16128c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III 1613e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener, 1614e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull Source src) { 1615e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III if (listener != null) { 1616e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III ImageInfo info = new ImageInfo(this); 1617e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III try { 1618e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III listener.onHeaderDecoded(this, info, src); 1619e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } finally { 1620e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III info.mDecoder = null; 1621e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 1622e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 1623e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 1624e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 16250c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 1626b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III * Create a {@link Drawable} from a {@code Source}. 1627b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III * 1628b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III * @param src representing the encoded image. 1629d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @param listener for learning the {@link ImageInfo ImageInfo} and changing any 1630c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III * default settings on the {@code ImageDecoder}. This will be called on 1631c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III * the same thread as {@code decodeDrawable} before that method returns. 16320a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * This is required in order to change any of the default settings. 1633b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III * @return Drawable for displaying the image. 1634ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III * @throws IOException if {@code src} is not found, is an unsupported 1635ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III * format, or cannot be decoded for any reason. 16360c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 16370a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @WorkerThread 1638ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III @NonNull 1639b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III public static Drawable decodeDrawable(@NonNull Source src, 1640c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III @NonNull OnHeaderDecodedListener listener) throws IOException { 1641c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III if (listener == null) { 1642c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III throw new IllegalArgumentException("listener cannot be null! " 1643c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III + "Use decodeDrawable(Source) to not have a listener"); 1644c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III } 1645c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III return decodeDrawableImpl(src, listener); 1646c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III } 1647c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III 16480a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @WorkerThread 1649c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III @NonNull 1650c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III private static Drawable decodeDrawableImpl(@NonNull Source src, 1651b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III @Nullable OnHeaderDecodedListener listener) throws IOException { 1652ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III try (ImageDecoder decoder = src.createImageDecoder()) { 1653e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III decoder.mSource = src; 1654e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III decoder.callHeaderDecoded(listener, src); 16550c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1656d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III if (decoder.mUnpremultipliedRequired) { 1657ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III // Though this could be supported (ignored) for opaque images, 1658ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III // it seems better to always report this error. 1659ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III throw new IllegalStateException("Cannot decode a Drawable " + 1660ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III "with unpremultiplied pixels!"); 1661ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 16620c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1663ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III if (decoder.mMutable) { 1664ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III throw new IllegalStateException("Cannot decode a mutable " + 1665ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III "Drawable!"); 1666ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III } 16670c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 166866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // this call potentially manipulates the decoder so it must be performed prior to 166966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // decoding the bitmap and after decode set the density on the resulting bitmap 16707d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III final int srcDensity = decoder.computeDensity(src); 1671671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III if (decoder.mAnimated) { 1672671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III // AnimatedImageDrawable calls postProcessAndRelease only if 1673e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III // mPostProcessor exists. 1674e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III ImageDecoder postProcessPtr = decoder.mPostProcessor == null ? 1675671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III null : decoder; 1676671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III Drawable d = new AnimatedImageDrawable(decoder.mNativePtr, 1677671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III postProcessPtr, decoder.mDesiredWidth, 167866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger decoder.mDesiredHeight, srcDensity, 167966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger src.computeDstDensity(), decoder.mCropRect, 1680671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III decoder.mInputStream, decoder.mAssetFd); 1681671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III // d has taken ownership of these objects. 1682671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III decoder.mInputStream = null; 1683671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III decoder.mAssetFd = null; 1684671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III return d; 1685671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III } 1686671cce2605ed50c9aba73ab5bd530cb7741c53cdLeon Scroggins III 1687c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III Bitmap bm = decoder.decodeBitmapInternal(); 168866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger bm.setDensity(srcDensity); 16890c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 169066c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger Resources res = src.getResources(); 16910c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III byte[] np = bm.getNinePatchChunk(); 16920c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III if (np != null && NinePatch.isNinePatchChunk(np)) { 16930c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III Rect opticalInsets = new Rect(); 16940c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III bm.getOpticalInsets(opticalInsets); 16952f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III Rect padding = decoder.mOutPaddingRect; 16962f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III if (padding == null) { 16972f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III padding = new Rect(); 16982f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III } 16990c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III nGetPadding(decoder.mNativePtr, padding); 17000c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III return new NinePatchDrawable(res, bm, np, padding, 17010c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III opticalInsets, null); 17020c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 17030c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 17040c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III return new BitmapDrawable(res, bm); 17050c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 17060c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 17070c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 17080c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III /** 17090a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * Create a {@link Drawable} from a {@code Source}. 17100a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 1711d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>Since there is no {@link OnHeaderDecodedListener OnHeaderDecodedListener}, 1712d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * the default settings will be used. In order to change any settings, call 17130a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * {@link #decodeDrawable(Source, OnHeaderDecodedListener)} instead.</p> 17140a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 17150a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * @param src representing the encoded image. 17160a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * @return Drawable for displaying the image. 17170a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * @throws IOException if {@code src} is not found, is an unsupported 17180a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * format, or cannot be decoded for any reason. 1719b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III */ 17200a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @WorkerThread 1721b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III @NonNull 1722b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III public static Drawable decodeDrawable(@NonNull Source src) 1723b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III throws IOException { 1724c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III return decodeDrawableImpl(src, null); 1725b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III } 1726b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III 1727b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III /** 1728b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III * Create a {@link Bitmap} from a {@code Source}. 1729b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III * 1730b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III * @param src representing the encoded image. 1731d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * @param listener for learning the {@link ImageInfo ImageInfo} and changing any 1732c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III * default settings on the {@code ImageDecoder}. This will be called on 1733c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III * the same thread as {@code decodeBitmap} before that method returns. 17340a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * This is required in order to change any of the default settings. 1735b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III * @return Bitmap containing the image. 1736ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III * @throws IOException if {@code src} is not found, is an unsupported 1737ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III * format, or cannot be decoded for any reason. 17380c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III */ 17390a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @WorkerThread 1740ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III @NonNull 1741b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III public static Bitmap decodeBitmap(@NonNull Source src, 1742c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III @NonNull OnHeaderDecodedListener listener) throws IOException { 1743c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III if (listener == null) { 1744c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III throw new IllegalArgumentException("listener cannot be null! " 1745c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III + "Use decodeBitmap(Source) to not have a listener"); 1746c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III } 1747c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III return decodeBitmapImpl(src, listener); 1748c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III } 1749c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III 17500a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @WorkerThread 1751c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III @NonNull 1752c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III private static Bitmap decodeBitmapImpl(@NonNull Source src, 1753b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III @Nullable OnHeaderDecodedListener listener) throws IOException { 1754ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III try (ImageDecoder decoder = src.createImageDecoder()) { 1755e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III decoder.mSource = src; 1756e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III decoder.callHeaderDecoded(listener, src); 17570c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 175866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // this call potentially manipulates the decoder so it must be performed prior to 175966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // decoding the bitmap 17607d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III final int srcDensity = decoder.computeDensity(src); 1761c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III Bitmap bm = decoder.decodeBitmapInternal(); 176266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger bm.setDensity(srcDensity); 17632f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III 17642f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III Rect padding = decoder.mOutPaddingRect; 17652f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III if (padding != null) { 17662f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III byte[] np = bm.getNinePatchChunk(); 17672f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III if (np != null && NinePatch.isNinePatchChunk(np)) { 17682f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III nGetPadding(decoder.mNativePtr, padding); 17692f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III } 17702f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III } 17712f1b06b58fc3c496832afc9b6ceeb2a36ef4bfa6Leon Scroggins III 177266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger return bm; 177366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 177466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 177566c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 177666c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // This method may modify the decoder so it must be called prior to performing the decode 17777d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III private int computeDensity(@NonNull Source src) { 177866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // if the caller changed the size then we treat the density as unknown 17797d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III if (this.requestedResize()) { 178066c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger return Bitmap.DENSITY_NONE; 178166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 178266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 17837d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III final int srcDensity = src.getDensity(); 17847d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III if (srcDensity == Bitmap.DENSITY_NONE) { 17857d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III return srcDensity; 17867d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III } 17877d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III 17887d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III // Scaling up nine-patch divs is imprecise and is better handled 17897d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III // at draw time. An app won't be relying on the internal Bitmap's 17907d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III // size, so it is safe to let NinePatchDrawable handle scaling. 17917d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III // mPostProcessor disables nine-patching, so behave normally if 17927d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III // it is present. 17937d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III if (mIsNinePatch && mPostProcessor == null) { 17947d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III return srcDensity; 17957d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III } 17967d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III 179766c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // Special stuff for compatibility mode: if the target density is not 179866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // the same as the display density, but the resource -is- the same as 179966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // the display density, then don't scale it down to the target density. 180066c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // This allows us to load the system's density-correct resources into 180166c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // an application in compatibility mode, without scaling those down 180266c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // to the compatibility density only to have them scaled back up when 180366c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger // drawn to the screen. 180466c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger Resources res = src.getResources(); 180566c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger if (res != null && res.getDisplayMetrics().noncompatDensityDpi == srcDensity) { 180666c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger return srcDensity; 18070c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 180866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 18097d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III final int dstDensity = src.computeDstDensity(); 18107d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III if (srcDensity == dstDensity) { 18117d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III return srcDensity; 18127d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III } 18137d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III 18148290eaba47b99398fbe0bd59138f902bde558ecbLeon Scroggins III // For P and above, only resize if it would be a downscale. Scale up prior 18158290eaba47b99398fbe0bd59138f902bde558ecbLeon Scroggins III // to P in case the app relies on the Bitmap's size without considering density. 18167d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III if (srcDensity < dstDensity && sApiLevel >= Build.VERSION_CODES.P) { 18178290eaba47b99398fbe0bd59138f902bde558ecbLeon Scroggins III return srcDensity; 181866c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger } 181966c6d78908e0203a497c2e97398c824b2591ea19Derek Sollenberger 18208290eaba47b99398fbe0bd59138f902bde558ecbLeon Scroggins III float scale = (float) dstDensity / srcDensity; 18217d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III int scaledWidth = (int) (mWidth * scale + 0.5f); 18227d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III int scaledHeight = (int) (mHeight * scale + 0.5f); 18237d940ba43d15836ccf32f373c778eebffacf1f5aLeon Scroggins III this.setTargetSize(scaledWidth, scaledHeight); 18248290eaba47b99398fbe0bd59138f902bde558ecbLeon Scroggins III return dstDensity; 18250c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III } 18260c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III 1827e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @NonNull 18281fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III private String getMimeType() { 18291fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III return nGetMimeType(mNativePtr); 18301fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III } 18311fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III 18321a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III @Nullable 18331a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private ColorSpace getColorSpace() { 18341a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III return nGetColorSpace(mNativePtr); 18351a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III } 18361a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III 1837b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III /** 18380a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * Create a {@link Bitmap} from a {@code Source}. 18390a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 1840d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * <p>Since there is no {@link OnHeaderDecodedListener OnHeaderDecodedListener}, 1841d84c652a4ebbdd8a42d09e28e2d3d83962a0350dLeon Scroggins III * the default settings will be used. In order to change any settings, call 18420a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * {@link #decodeBitmap(Source, OnHeaderDecodedListener)} instead.</p> 18430a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * 18440a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * @param src representing the encoded image. 18450a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * @return Bitmap containing the image. 18460a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * @throws IOException if {@code src} is not found, is an unsupported 18470a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III * format, or cannot be decoded for any reason. 1848b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III */ 18490a87cb3128a7fe8a999544ec1187159d82aa09ddLeon Scroggins III @WorkerThread 1850b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III @NonNull 1851b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III public static Bitmap decodeBitmap(@NonNull Source src) throws IOException { 1852c9aa856559ca3b08c9409164b2f86c218c71505fLeon Scroggins III return decodeBitmapImpl(src, null); 1853b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III } 1854b1cc8e64374832c8b296f609bebabff068ded460Leon Scroggins III 18558c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III /** 18568c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III * Private method called by JNI. 18578c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III */ 18588c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III @SuppressWarnings("unused") 1859e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private int postProcessAndRelease(@NonNull Canvas canvas) { 18608c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III try { 1861e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III return mPostProcessor.onPostProcess(canvas); 18628c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III } finally { 18638c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III canvas.release(); 18648c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III } 18658c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III } 18668c9d8f2aec65e449005a4a69c54f691ebd514e52Leon Scroggins III 1867e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III /** 1868e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III * Private method called by JNI. 1869e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III */ 1870e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @SuppressWarnings("unused") 1871cf7294fda671a39e6aa21da30be0dac261d71638Leon Scroggins III private void onPartialImage(@DecodeException.Error int error, @Nullable Throwable cause) 18721d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III throws DecodeException { 18731d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III DecodeException exception = new DecodeException(error, cause, mSource); 18741d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III if (mOnPartialImageListener == null 18751d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III || !mOnPartialImageListener.onPartialImage(exception)) { 18761d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III throw exception; 18771d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III } 1878e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III } 1879e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III 18801d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III private static native ImageDecoder nCreate(long asset, Source src) throws IOException; 18811d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III private static native ImageDecoder nCreate(ByteBuffer buffer, int position, 18821d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III int limit, Source src) throws IOException; 18831d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III private static native ImageDecoder nCreate(byte[] data, int offset, int length, 18841d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III Source src) throws IOException; 18851d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III private static native ImageDecoder nCreate(InputStream is, byte[] storage, 18861d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III Source src) throws IOException; 1887e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III // The fd must be seekable. 18881d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III private static native ImageDecoder nCreate(FileDescriptor fd, Source src) throws IOException; 1889ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III @NonNull 18900c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III private static native Bitmap nDecodeBitmap(long nativePtr, 18911d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III @NonNull ImageDecoder decoder, 18921d2bf2b846f0a98f7403bbc791adb2969685d87aLeon Scroggins III boolean doPostProcess, 18930c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III int width, int height, 1894e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III @Nullable Rect cropRect, boolean mutable, 1895d62f27250ab99d67242f1de293a31c12c397beb2Leon Scroggins III int allocator, boolean unpremulRequired, 18961a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III boolean conserveMemory, boolean decodeAsAlphaMask, 18971a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III @Nullable ColorSpace desiredColorSpace) 1898ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III throws IOException; 1899e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private static native Size nGetSampledSize(long nativePtr, 1900e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III int sampleSize); 1901e5de9aa4a9bab9c4d8288212d6352a65e9808737Leon Scroggins III private static native void nGetPadding(long nativePtr, @NonNull Rect outRect); 1902ed074fd70011cf804a14b5cf53ffd4b529c5f367Leon Scroggins III private static native void nClose(long nativePtr); 19031fad09d4d3f43112abd842da4c94cf00fb1cb46dLeon Scroggins III private static native String nGetMimeType(long nativePtr); 19041a69f4598faef083d0123bb9b6bfcd6acfdec4e0Leon Scroggins III private static native ColorSpace nGetColorSpace(long nativePtr); 19050c01dbf8f283b7bcaf6babf540a501735c73b4f5Leon Scroggins III} 1906