BitmapFactory.java revision ca32021b43f326af7d3f4ae041f8db297f98a518
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetManager;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
21787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guyimport android.os.Trace;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.DisplayMetrics;
23b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasaniimport android.util.Log;
24eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chenimport android.util.TypedValue;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chenimport java.io.FileDescriptor;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
29eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chenimport java.io.InputStream;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
32eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen * Creates Bitmap objects from various sources, including files, streams,
33eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen * and byte-arrays.
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class BitmapFactory {
367b2f8b8fb7064a1d3b6d942b978c30c24c9d7299Romain Guy    private static final int DECODE_BUFFER_SIZE = 16 * 1024;
377b2f8b8fb7064a1d3b6d942b978c30c24c9d7299Romain Guy
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class Options {
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Create a default Options object, which if left unchanged will give
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the same result from the decoder as if null were passed.
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Options() {
44207b3ab604bcbe47fa55f26f358cde60cf8a784dRomain Guy            inDither = false;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            inScaled = true;
461abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik            inPremultiplied = true;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5037f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase         * If set, decode methods that take the Options object will attempt to
51c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * reuse this bitmap when loading content. If the decode operation
52c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * cannot use this bitmap, the decode method will return
53c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * <code>null</code> and will throw an IllegalArgumentException. The
54c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * current implementation necessitates that the reused bitmap be
55c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * mutable, and the resulting reused bitmap will continue to remain
56c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * mutable even when decoding a resource which would normally result in
57c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * an immutable bitmap.</p>
589f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik         *
59c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * <p>As of {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, any
60c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * mutable bitmap can be reused to decode any other bitmaps as long as
61c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * the resulting {@link Bitmap#getByteCount() byte count} of the decoded
62c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * bitmap is less than or equal to the {@link
63c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * Bitmap#getAllocationByteCount() allocated byte count} of the reused
64c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * bitmap. This can be because the intrinsic size is smaller, or its
65c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * size post scaling (for density / sample size) is smaller.</p>
66905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik         *
67c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * <p>Prior to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}
68c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * additional constraints apply: The image being decoded (whether as a
69c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * resource or as a stream) must be in jpeg or png format. Only equal
70c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * sized bitmaps are supported, with {@link #inSampleSize} set to 1.
71c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * Additionally, the {@link android.graphics.Bitmap.Config
72c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * configuration} of the reused bitmap will override the setting of
73c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * {@link #inPreferredConfig}, if set.</p>
7437f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase         *
7537f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase         * <p>You should still always use the returned Bitmap of the decode
7637f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase         * method and not assume that reusing the bitmap worked, due to the
7737f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase         * constraints outlined above and failure situations that can occur.
7837f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase         * Checking whether the return value matches the value of the inBitmap
79905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik         * set in the Options structure will indicate if the bitmap was reused,
80c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * but in all cases you should use the Bitmap returned by the decoding
81c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * function to ensure that you are using the bitmap that was used as the
82c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * decode destination.</p>
83c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         *
84c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik         * @see Bitmap#reconfigure(int,int,Config)
8537f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase         */
8637f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase        public Bitmap inBitmap;
8737f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase
8837f74cad46c6f1799aec3c52e8f47598237f43d4Chet Haase        /**
892361098da3b9d9c3eeed410dc72ba62c0e9177cfRomain Guy         * If set, decode methods will always return a mutable Bitmap instead of
902361098da3b9d9c3eeed410dc72ba62c0e9177cfRomain Guy         * an immutable one. This can be used for instance to programmatically apply
912361098da3b9d9c3eeed410dc72ba62c0e9177cfRomain Guy         * effects to a Bitmap loaded through BitmapFactory.
922361098da3b9d9c3eeed410dc72ba62c0e9177cfRomain Guy         */
932361098da3b9d9c3eeed410dc72ba62c0e9177cfRomain Guy        @SuppressWarnings({"UnusedDeclaration"}) // used in native code
942361098da3b9d9c3eeed410dc72ba62c0e9177cfRomain Guy        public boolean inMutable;
952361098da3b9d9c3eeed410dc72ba62c0e9177cfRomain Guy
962361098da3b9d9c3eeed410dc72ba62c0e9177cfRomain Guy        /**
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If set to true, the decoder will return null (no bitmap), but
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the out... fields will still be set, allowing the caller to query
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the bitmap without having to allocate the memory for its pixels.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean inJustDecodeBounds;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If set to a value > 1, requests the decoder to subsample the original
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * image, returning a smaller image to save memory. The sample size is
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the number of pixels in either dimension that correspond to a single
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * pixel in the decoded bitmap. For example, inSampleSize == 4 returns
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * an image that is 1/4 the width/height of the original, and 1/16 the
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * number of pixels. Any value <= 1 is treated the same as 1. Note: the
110758333d70a749fb50276057abc585cbc0decc8d4Adam Koch         * decoder uses a final value based on powers of 2, any other value will
111758333d70a749fb50276057abc585cbc0decc8d4Adam Koch         * be rounded down to the nearest power of 2.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int inSampleSize;
114eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If this is non-null, the decoder will try to decode into this
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * internal configuration. If it is null, or the request cannot be met,
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the decoder will try to pick the best matching config based on the
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * system's screen depth, and characteristics of the original image such
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * as if it has per-pixel alpha (requiring a config that also does).
121207b3ab604bcbe47fa55f26f358cde60cf8a784dRomain Guy         *
122207b3ab604bcbe47fa55f26f358cde60cf8a784dRomain Guy         * Image are loaded with the {@link Bitmap.Config#ARGB_8888} config by
123207b3ab604bcbe47fa55f26f358cde60cf8a784dRomain Guy         * default.
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
125207b3ab604bcbe47fa55f26f358cde60cf8a784dRomain Guy        public Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888;
126eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1281abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * If true (which is the default), the resulting bitmap will have its
1291abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * color channels pre-multipled by the alpha channel.
1301abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         *
1311abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * <p>This should NOT be set to false for images to be directly drawn by
1321abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * the view system or through a {@link Canvas}. The view system and
1331abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * {@link Canvas} assume all drawn images are pre-multiplied to simplify
1341abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * draw-time blending, and will throw a RuntimeException when
1351abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * un-premultiplied are drawn.</p>
1361abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         *
1371abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * <p>This is likely only useful if you want to manipulate raw encoded
1381abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * image data, e.g. with RenderScript or custom OpenGL.</p>
1391abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         *
1401abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * <p>This does not affect bitmaps without an alpha channel.</p>
1411abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         *
1421abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * @see Bitmap#hasAlpha()
1431abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         * @see Bitmap#isPremultiplied()
1441abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik         */
1451abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        public boolean inPremultiplied;
1461abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik
1471abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        /**
1487341d7a104b47996445d069a695e155a07184606Dianne Hackborn         * If dither is true, the decoder will attempt to dither the decoded
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * image.
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean inDither;
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
15411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * The pixel density to use for the bitmap.  This will always result
15511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * in the returned bitmap having a density set for it (see
1566e1df0e981c8c588e411b8ad6e55554fe4815655Gilles Debunne         * {@link Bitmap#setDensity(int) Bitmap.setDensity(int)}).  In addition,
15711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * if {@link #inScaled} is set (which it is by default} and this
15811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * density does not match {@link #inTargetDensity}, then the bitmap
15911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * will be scaled to the target density before being returned.
16011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
16111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>If this is 0,
16211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory#decodeResource(Resources, int)},
16311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
16411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * and {@link BitmapFactory#decodeResourceStream}
16511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * will fill in the density associated with the resource.  The other
16611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * functions will leave it as-is and no density will be applied.
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
16811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inTargetDensity
16911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScreenDensity
17011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScaled
17111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see Bitmap#setDensity(int)
17211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see android.util.DisplayMetrics#densityDpi
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int inDensity;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
17711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * The pixel density of the destination this bitmap will be drawn to.
17811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * This is used in conjunction with {@link #inDensity} and
17911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link #inScaled} to determine if and how to scale the bitmap before
18011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * returning it.
18111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
18211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>If this is 0,
18311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory#decodeResource(Resources, int)},
18411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
18511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * and {@link BitmapFactory#decodeResourceStream}
18611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * will fill in the density associated the Resources object's
18711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * DisplayMetrics.  The other
18811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * functions will leave it as-is and no scaling for density will be
18911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * performed.
19011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
19111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inDensity
19211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScreenDensity
19311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScaled
19411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see android.util.DisplayMetrics#densityDpi
19511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         */
19611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        public int inTargetDensity;
19711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
19811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        /**
19911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * The pixel density of the actual screen that is being used.  This is
20011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * purely for applications running in density compatibility code, where
20111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link #inTargetDensity} is actually the density the application
20211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * sees rather than the real screen density.
20311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
20411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>By setting this, you
20511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * allow the loading code to avoid scaling a bitmap that is currently
20611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * in the screen density up/down to the compatibility density.  Instead,
20711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * if {@link #inDensity} is the same as {@link #inScreenDensity}, the
20811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * bitmap will be left as-is.  Anything using the resulting bitmap
20911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * must also used {@link Bitmap#getScaledWidth(int)
21011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * Bitmap.getScaledWidth} and {@link Bitmap#getScaledHeight
21111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * Bitmap.getScaledHeight} to account for any different between the
21211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * bitmap's density and the target's density.
21311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
21411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>This is never set automatically for the caller by
21511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory} itself.  It must be explicitly set, since the
21611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * caller must deal with the resulting bitmap in a density-aware way.
21711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
21811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inDensity
21911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inTargetDensity
22011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScaled
22111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see android.util.DisplayMetrics#densityDpi
22211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         */
22311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        public int inScreenDensity;
22411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
22511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        /**
22611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * When this flag is set, if {@link #inDensity} and
22711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link #inTargetDensity} are not 0, the
22811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * bitmap will be scaled to match {@link #inTargetDensity} when loaded,
22911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * rather than relying on the graphics system scaling it each time it
23011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * is drawn to a Canvas.
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
23211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>This flag is turned on by default and should be turned off if you need
23311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * a non-scaled version of the bitmap.  Nine-patch bitmaps ignore this
23411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * flag and are always scaled.
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean inScaled;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
239c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * If this is set to true, then the resulting bitmap will allocate its
240c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * pixels such that they can be purged if the system needs to reclaim
241c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * memory. In that instance, when the pixels need to be accessed again
242c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * (e.g. the bitmap is drawn, getPixels() is called), they will be
243c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * automatically re-decoded.
244c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         *
245c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * For the re-decode to happen, the bitmap must have access to the
246c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * encoded data, either by sharing a reference to the input
247c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * or by making a copy of it. This distinction is controlled by
248c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * inInputShareable. If this is true, then the bitmap may keep a shallow
249c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * reference to the input. If this is false, then the bitmap will
250c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * explicitly make a copy of the input data, and keep that. Even if
251c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * sharing is allowed, the implementation may still decide to make a
252c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * deep copy of the input data.
253c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         */
254c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed        public boolean inPurgeable;
255c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed
256c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed        /**
257c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * This field works in conjuction with inPurgeable. If inPurgeable is
258c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * false, then this field is ignored. If inPurgeable is true, then this
259c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * field determines whether the bitmap can share a reference to the
260c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * input data (inputstream, array, etc.) or if it must make a deep copy.
261c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         */
262c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed        public boolean inInputShareable;
263c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed
264c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed        /**
265953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen         * If inPreferQualityOverSpeed is set to true, the decoder will try to
266953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen         * decode the reconstructed image to a higher quality even at the
267953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen         * expense of the decoding speed. Currently the field only affects JPEG
268953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen         * decode, in the case of which a more accurate, but slightly slower,
269953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen         * IDCT method will be used instead.
270953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen         */
271953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen        public boolean inPreferQualityOverSpeed;
272953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen
273953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen        /**
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The resulting width of the bitmap, set independent of the state of
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * inJustDecodeBounds. However, if there is an error trying to decode,
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * outWidth will be set to -1.
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
278953f9094a2ec14594fa8501d5f3e2d9e300b1b62Wei-Ta Chen
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int outWidth;
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The resulting height of the bitmap, set independent of the state of
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * inJustDecodeBounds. However, if there is an error trying to decode,
28439c512b623eff1d7a7b17f68a42723fbda9bf483Romain Guy         * outHeight will be set to -1.
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int outHeight;
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If known, this string is set to the mimetype of the decoded image.
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If not know, or there is an error, it is set to null.
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String outMimeType;
293eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Temp storage to use for decoding.  Suggest 16K or so.
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public byte[] inTempStorage;
298eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private native void requestCancel();
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Flag to indicate that cancel has been called on this object.  This
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * is useful if there's an intermediary that wants to first decode the
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * bounds and then decode the image.  In that case the intermediary
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * can check, inbetween the bounds decode and the image decode, to see
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * if the operation is canceled.
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean mCancel;
309eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  This can be called from another thread while this options object is
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  inside a decode... call. Calling this will notify the decoder that
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  it should cancel its operation. This is not guaranteed to cancel
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  the decode, but if it does, the decoder... operation will return
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  null, or if inJustDecodeBounds is true, will set outWidth/outHeight
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  to -1
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void requestCancelDecode() {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCancel = true;
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            requestCancel();
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a file path into a bitmap. If the specified file name is null,
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or cannot be decoded into a bitmap, the function returns null.
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pathName complete path name for the file to be decoded.
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             image should be completely decoded, or just is size returned.
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image data could not be
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         decoded, or, if opts is non-null, if opts requested only the
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         size be returned (in opts.outWidth and opts.outHeight)
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeFile(String pathName, Options opts) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap bm = null;
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputStream stream = null;
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stream = new FileInputStream(pathName);
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bm = decodeStream(stream, null, opts);
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (Exception e) {
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*  do nothing.
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                If the exception happened on open, bm will be null.
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            */
345b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            Log.e("BitmapFactory", "Unable to decode stream: " + e);
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (stream != null) {
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    stream.close();
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (IOException e) {
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // do nothing here
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a file path into a bitmap. If the specified file name is null,
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or cannot be decoded into a bitmap, the function returns null.
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pathName complete path name for the file to be decoded.
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the resulting decoded bitmap, or null if it could not be decoded.
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeFile(String pathName) {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return decodeFile(pathName, null);
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a new Bitmap from an InputStream. This InputStream was obtained from
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * resources, which we pass to be able to scale the bitmap accordingly.
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
37311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public static Bitmap decodeResourceStream(Resources res, TypedValue value,
37411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            InputStream is, Rect pad, Options opts) {
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (opts == null) {
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            opts = new Options();
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (opts.inDensity == 0 && value != null) {
381a53b828635fce8b6b2d3e3377d74d72070056623Dianne Hackborn            final int density = value.density;
38211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            if (density == TypedValue.DENSITY_DEFAULT) {
38311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
38411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            } else if (density != TypedValue.DENSITY_NONE) {
38511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                opts.inDensity = density;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
38811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
38911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (opts.inTargetDensity == 0 && res != null) {
39011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
39111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        }
39211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
39311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return decodeStream(is, pad, opts);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
39711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Synonym for opening the given resource and calling
39811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * {@link #decodeResourceStream}.
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param res   The resources object containing the image data
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The resource id of the image data
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             image should be completely decoded, or just is size returned.
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image data could not be
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         decoded, or, if opts is non-null, if opts requested only the
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         size be returned (in opts.outWidth and opts.outHeight)
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeResource(Resources res, int id, Options opts) {
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap bm = null;
410650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy        InputStream is = null;
411650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final TypedValue value = new TypedValue();
414650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy            is = res.openRawResource(id, value);
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            bm = decodeResourceStream(res, value, is, null, opts);
417650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy        } catch (Exception e) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*  do nothing.
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                If the exception happened on open, bm will be null.
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                If it happened on close, bm is still valid.
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            */
422650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy        } finally {
423650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy            try {
424650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy                if (is != null) is.close();
425650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy            } catch (IOException e) {
426650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy                // Ignore
427650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy            }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
429650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy
430decc8cd41eca3770c8f5ee13d81b9cd5f0c25ccdChet Haase        if (bm == null && opts != null && opts.inBitmap != null) {
431decc8cd41eca3770c8f5ee13d81b9cd5f0c25ccdChet Haase            throw new IllegalArgumentException("Problem decoding into existing bitmap");
432decc8cd41eca3770c8f5ee13d81b9cd5f0c25ccdChet Haase        }
433decc8cd41eca3770c8f5ee13d81b9cd5f0c25ccdChet Haase
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
436eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
43811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Synonym for {@link #decodeResource(Resources, int, android.graphics.BitmapFactory.Options)}
43911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * will null Options.
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param res The resources object containing the image data
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The resource id of the image data
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image could not be decode.
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeResource(Resources res, int id) {
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return decodeResource(res, id, null);
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode an immutable bitmap from the specified byte array.
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param data byte array of compressed image data
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset offset into imageData for where the decoder should begin
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               parsing.
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param length the number of bytes, beginning at offset, to parse
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             image should be completely decoded, or just is size returned.
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image data could not be
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         decoded, or, if opts is non-null, if opts requested only the
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         size be returned (in opts.outWidth and opts.outHeight)
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) {
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((offset | length) < 0 || data.length < offset + length) {
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
466ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani
467787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy        Bitmap bm;
468787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy
469787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
470787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy        try {
471787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            bm = nativeDecodeByteArray(data, offset, length, opts);
472787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy
473787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            if (bm == null && opts != null && opts.inBitmap != null) {
474787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy                throw new IllegalArgumentException("Problem decoding into existing bitmap");
475787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            }
476787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            setDensityFromOptions(bm, opts);
477787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy        } finally {
478787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
479decc8cd41eca3770c8f5ee13d81b9cd5f0c25ccdChet Haase        }
480787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy
481decc8cd41eca3770c8f5ee13d81b9cd5f0c25ccdChet Haase        return bm;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
483eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode an immutable bitmap from the specified byte array.
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param data byte array of compressed image data
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset offset into imageData for where the decoder should begin
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               parsing.
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param length the number of bytes, beginning at offset, to parse
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image could not be decode.
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeByteArray(byte[] data, int offset, int length) {
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return decodeByteArray(data, offset, length, null);
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
496eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
498905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik     * Set the newly decoded bitmap's density based on the Options.
499905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik     */
500905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik    private static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {
501905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik        if (outputBitmap == null || opts == null) return;
502905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik
503905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik        final int density = opts.inDensity;
504905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik        if (density != 0) {
505905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            outputBitmap.setDensity(density);
506905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            final int targetDensity = opts.inTargetDensity;
507905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
508905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik                return;
509905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            }
510905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik
511905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            byte[] np = outputBitmap.getNinePatchChunk();
512905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
513905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            if (opts.inScaled || isNinePatch) {
514905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik                outputBitmap.setDensity(targetDensity);
515905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            }
516905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik        } else if (opts.inBitmap != null) {
517905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            // bitmap was reused, ensure density is reset
518905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik            outputBitmap.setDensity(Bitmap.getDefaultDensity());
519905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik        }
520905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik    }
521905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik
522905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik    /**
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode an input stream into a bitmap. If the input stream is null, or
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cannot be used to decode a bitmap, the function returns null.
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The stream's position will be where ever it was after the encoded data
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was read.
527eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen     *
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param is The input stream that holds the raw data to be decoded into a
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *           bitmap.
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param outPadding If not null, return the padding rect for the bitmap if
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   it exists, otherwise set padding to [-1,-1,-1,-1]. If
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   no bitmap is returned (null) then padding is
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   unchanged.
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             image should be completely decoded, or just is size returned.
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image data could not be
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         decoded, or, if opts is non-null, if opts requested only the
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         size be returned (in opts.outWidth and opts.outHeight)
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we don't throw in this case, thus allowing the caller to only check
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the cache, and not force the image to be decoded.
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (is == null) {
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
546eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
547ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III        Bitmap bm = null;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
550787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy        try {
551ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III            boolean decodeGenericStream = true;
552787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            if (is instanceof AssetManager.AssetInputStream) {
553787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy                final int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
554787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy                bm = nativeDecodeAsset(asset, outPadding, opts);
555ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                // Do not follow the normal case.
556ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                decodeGenericStream = false;
557ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III            } else if (is instanceof FileInputStream) {
558ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                try {
559ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                    FileDescriptor fd = ((FileInputStream) is).getFD();
560ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                    // decodeFileDescriptor will take care of throwing the IAE and
561ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                    // calling setDensityFromOptions.
562ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                    return decodeFileDescriptor(fd, outPadding, opts);
563ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                } catch (IOException e) {
564ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                    // Fall through to nativeDecodeStream.
565ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                }
566ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III            }
567ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III
568ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III            if (decodeGenericStream) {
569787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy                byte [] tempStorage = null;
570787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy                if (opts != null) tempStorage = opts.inTempStorage;
571787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy                if (tempStorage == null) tempStorage = new byte[DECODE_BUFFER_SIZE];
572787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy                bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
573787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            }
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
575787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            if (bm == null && opts != null && opts.inBitmap != null) {
576787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy                throw new IllegalArgumentException("Problem decoding into existing bitmap");
577787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            }
5787b2f8b8fb7064a1d3b6d942b978c30c24c9d7299Romain Guy
579787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            setDensityFromOptions(bm, opts);
580787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy        } finally {
581787e35793f47abdb6cc10f328cd58d362c7bd250Romain Guy            Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
582decc8cd41eca3770c8f5ee13d81b9cd5f0c25ccdChet Haase        }
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
586905e8246ef0bd20ee28d81ce3da0c5e5fc8e3913Chris Craik
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode an input stream into a bitmap. If the input stream is null, or
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cannot be used to decode a bitmap, the function returns null.
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The stream's position will be where ever it was after the encoded data
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was read.
592eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen     *
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param is The input stream that holds the raw data to be decoded into a
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *           bitmap.
59503f0292744094ec107ffce71301c394503a31dedGilles Debunne     * @return The decoded bitmap, or null if the image data could not be decoded.
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeStream(InputStream is) {
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return decodeStream(is, null, null);
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a bitmap from the file descriptor. If the bitmap cannot be decoded
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * return null. The position within the descriptor will not be changed when
6047341d7a104b47996445d069a695e155a07184606Dianne Hackborn     * this returns, so the descriptor can be used again as-is.
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param fd The file descriptor containing the bitmap data to decode
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param outPadding If not null, return the padding rect for the bitmap if
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   it exists, otherwise set padding to [-1,-1,-1,-1]. If
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   no bitmap is returned (null) then padding is
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   unchanged.
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
612ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III     *             image should be completely decoded, or just its size returned.
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the decoded bitmap, or null
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
616ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III        Bitmap bm;
617ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III
618ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeFileDescriptor");
619ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III        try {
620ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III            if (nativeIsSeekable(fd)) {
621ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
622ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III            } else {
623ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                FileInputStream fis = new FileInputStream(fd);
624ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                // FIXME: If nativeDecodeStream grabbed the pointer to tempStorage
625ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                // from Options, this code would not need to be duplicated.
626ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                byte [] tempStorage = null;
627ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                if (opts != null) tempStorage = opts.inTempStorage;
628ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                if (tempStorage == null) tempStorage = new byte[DECODE_BUFFER_SIZE];
629ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                try {
630ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                    bm = nativeDecodeStream(fis, tempStorage, outPadding, opts);
631ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                } finally {
632ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                    try {
633ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                        fis.close();
634ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                    } catch (Throwable t) {/* ignore */}
635ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III                }
636ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III            }
637ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III
638a9d0d47076ecf2d1739bb3534abc9deead8ebebdOwen Lin            if (bm == null && opts != null && opts.inBitmap != null) {
639a9d0d47076ecf2d1739bb3534abc9deead8ebebdOwen Lin                throw new IllegalArgumentException("Problem decoding into existing bitmap");
640a9d0d47076ecf2d1739bb3534abc9deead8ebebdOwen Lin            }
641ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III
642ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III            setDensityFromOptions(bm, opts);
643ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III        } finally {
644ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III            Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
645decc8cd41eca3770c8f5ee13d81b9cd5f0c25ccdChet Haase        }
646ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III        return bm;
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
648eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a bitmap from the file descriptor. If the bitmap cannot be decoded
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * return null. The position within the descriptor will not be changed when
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this returns, so the descriptor can be used again as is.
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param fd The file descriptor containing the bitmap data to decode
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the decoded bitmap, or null
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeFileDescriptor(FileDescriptor fd) {
658984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen        return decodeFileDescriptor(fd, null, null);
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
660eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Rect padding, Options opts);
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Rect padding, Options opts);
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts);
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int length, Options opts);
668a9d0d47076ecf2d1739bb3534abc9deead8ebebdOwen Lin    private static native boolean nativeIsSeekable(FileDescriptor fd);
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
670