BitmapFactory.java revision ab4a0c164b5a44d5bfd37069cfe499db31e7620c
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;
21984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissenimport android.os.MemoryFile;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.DisplayMetrics;
23eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chenimport android.util.TypedValue;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.BufferedInputStream;
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 {
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class Options {
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Create a default Options object, which if left unchanged will give
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the same result from the decoder as if null were passed.
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Options() {
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            inDither = true;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            inScaled = true;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If set to true, the decoder will return null (no bitmap), but
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the out... fields will still be set, allowing the caller to query
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the bitmap without having to allocate the memory for its pixels.
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean inJustDecodeBounds;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If set to a value > 1, requests the decoder to subsample the original
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * image, returning a smaller image to save memory. The sample size is
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the number of pixels in either dimension that correspond to a single
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * pixel in the decoded bitmap. For example, inSampleSize == 4 returns
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * an image that is 1/4 the width/height of the original, and 1/16 the
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * number of pixels. Any value <= 1 is treated the same as 1. Note: the
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * decoder will try to fulfill this request, but the resulting bitmap
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * may have different dimensions that precisely what has been requested.
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Also, powers of 2 are often faster/easier for the decoder to honor.
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int inSampleSize;
65eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If this is non-null, the decoder will try to decode into this
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * internal configuration. If it is null, or the request cannot be met,
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the decoder will try to pick the best matching config based on the
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * system's screen depth, and characteristics of the original image such
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * as if it has per-pixel alpha (requiring a config that also does).
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Bitmap.Config inPreferredConfig;
74eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
767341d7a104b47996445d069a695e155a07184606Dianne Hackborn         * If dither is true, the decoder will attempt to dither the decoded
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * image.
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean inDither;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
8211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * The pixel density to use for the bitmap.  This will always result
8311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * in the returned bitmap having a density set for it (see
8411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link Bitmap#setDensity(int) Bitmap.setDensity(int)).  In addition,
8511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * if {@link #inScaled} is set (which it is by default} and this
8611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * density does not match {@link #inTargetDensity}, then the bitmap
8711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * will be scaled to the target density before being returned.
8811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
8911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>If this is 0,
9011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory#decodeResource(Resources, int)},
9111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
9211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * and {@link BitmapFactory#decodeResourceStream}
9311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * will fill in the density associated with the resource.  The other
9411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * functions will leave it as-is and no density will be applied.
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
9611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inTargetDensity
9711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScreenDensity
9811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScaled
9911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see Bitmap#setDensity(int)
10011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see android.util.DisplayMetrics#densityDpi
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int inDensity;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
10511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * The pixel density of the destination this bitmap will be drawn to.
10611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * This is used in conjunction with {@link #inDensity} and
10711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link #inScaled} to determine if and how to scale the bitmap before
10811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * returning it.
10911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
11011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>If this is 0,
11111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory#decodeResource(Resources, int)},
11211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
11311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * and {@link BitmapFactory#decodeResourceStream}
11411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * will fill in the density associated the Resources object's
11511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * DisplayMetrics.  The other
11611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * functions will leave it as-is and no scaling for density will be
11711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * performed.
11811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
11911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inDensity
12011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScreenDensity
12111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScaled
12211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see android.util.DisplayMetrics#densityDpi
12311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         */
12411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        public int inTargetDensity;
12511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
12611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        /**
12711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * The pixel density of the actual screen that is being used.  This is
12811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * purely for applications running in density compatibility code, where
12911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link #inTargetDensity} is actually the density the application
13011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * sees rather than the real screen density.
13111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
13211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>By setting this, you
13311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * allow the loading code to avoid scaling a bitmap that is currently
13411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * in the screen density up/down to the compatibility density.  Instead,
13511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * if {@link #inDensity} is the same as {@link #inScreenDensity}, the
13611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * bitmap will be left as-is.  Anything using the resulting bitmap
13711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * must also used {@link Bitmap#getScaledWidth(int)
13811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * Bitmap.getScaledWidth} and {@link Bitmap#getScaledHeight
13911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * Bitmap.getScaledHeight} to account for any different between the
14011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * bitmap's density and the target's density.
14111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
14211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>This is never set automatically for the caller by
14311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link BitmapFactory} itself.  It must be explicitly set, since the
14411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * caller must deal with the resulting bitmap in a density-aware way.
14511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         *
14611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inDensity
14711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inTargetDensity
14811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see #inScaled
14911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * @see android.util.DisplayMetrics#densityDpi
15011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         */
15111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        public int inScreenDensity;
15211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
15311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        /**
15411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * When this flag is set, if {@link #inDensity} and
15511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * {@link #inTargetDensity} are not 0, the
15611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * bitmap will be scaled to match {@link #inTargetDensity} when loaded,
15711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * rather than relying on the graphics system scaling it each time it
15811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * is drawn to a Canvas.
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
16011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * <p>This flag is turned on by default and should be turned off if you need
16111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * a non-scaled version of the bitmap.  Nine-patch bitmaps ignore this
16211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn         * flag and are always scaled.
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean inScaled;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
167c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * If this is set to true, then the resulting bitmap will allocate its
168c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * pixels such that they can be purged if the system needs to reclaim
169c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * memory. In that instance, when the pixels need to be accessed again
170c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * (e.g. the bitmap is drawn, getPixels() is called), they will be
171c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * automatically re-decoded.
172c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         *
173c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * For the re-decode to happen, the bitmap must have access to the
174c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * encoded data, either by sharing a reference to the input
175c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * or by making a copy of it. This distinction is controlled by
176c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * inInputShareable. If this is true, then the bitmap may keep a shallow
177c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * reference to the input. If this is false, then the bitmap will
178c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * explicitly make a copy of the input data, and keep that. Even if
179c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * sharing is allowed, the implementation may still decide to make a
180c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * deep copy of the input data.
181c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         */
182c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed        public boolean inPurgeable;
183c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed
184c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed        /**
185c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * This field works in conjuction with inPurgeable. If inPurgeable is
186c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * false, then this field is ignored. If inPurgeable is true, then this
187c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * field determines whether the bitmap can share a reference to the
188c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         * input data (inputstream, array, etc.) or if it must make a deep copy.
189c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed         */
190c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed        public boolean inInputShareable;
191c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed
192c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed        /**
1931b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         * Normally bitmap allocations count against the dalvik heap, which
1941b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         * means they help trigger GCs when a lot have been allocated. However,
1951b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         * in rare cases, the caller may want to allocate the bitmap outside of
1961b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         * that heap. To request that, set inNativeAlloc to true. In these
1971b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         * rare instances, it is solely up to the caller to ensure that OOM is
1981b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         * managed explicitly by calling bitmap.recycle() as soon as such a
1991b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         * bitmap is no longer needed.
2001b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         *
2011b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         * @hide pending API council approval
2021b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed         */
2031b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed        public boolean inNativeAlloc;
2041b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed
2051b22b979256cf163ab9bbfd4fcfa16a8ce862ed1Mike Reed        /**
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The resulting width of the bitmap, set independent of the state of
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * inJustDecodeBounds. However, if there is an error trying to decode,
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * outWidth will be set to -1.
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int outWidth;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The resulting height of the bitmap, set independent of the state of
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * inJustDecodeBounds. However, if there is an error trying to decode,
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * outHeight will be set to -1.
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int outHeight;
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If known, this string is set to the mimetype of the decoded image.
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If not know, or there is an error, it is set to null.
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String outMimeType;
224eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Temp storage to use for decoding.  Suggest 16K or so.
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public byte[] inTempStorage;
229eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private native void requestCancel();
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Flag to indicate that cancel has been called on this object.  This
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * is useful if there's an intermediary that wants to first decode the
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * bounds and then decode the image.  In that case the intermediary
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * can check, inbetween the bounds decode and the image decode, to see
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * if the operation is canceled.
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean mCancel;
240eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  This can be called from another thread while this options object is
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  inside a decode... call. Calling this will notify the decoder that
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  it should cancel its operation. This is not guaranteed to cancel
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  the decode, but if it does, the decoder... operation will return
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  null, or if inJustDecodeBounds is true, will set outWidth/outHeight
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  to -1
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void requestCancelDecode() {
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCancel = true;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            requestCancel();
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a file path into a bitmap. If the specified file name is null,
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or cannot be decoded into a bitmap, the function returns null.
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pathName complete path name for the file to be decoded.
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             image should be completely decoded, or just is size returned.
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image data could not be
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         decoded, or, if opts is non-null, if opts requested only the
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         size be returned (in opts.outWidth and opts.outHeight)
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeFile(String pathName, Options opts) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap bm = null;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputStream stream = null;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stream = new FileInputStream(pathName);
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bm = decodeStream(stream, null, opts);
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (Exception e) {
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*  do nothing.
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                If the exception happened on open, bm will be null.
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            */
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (stream != null) {
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    stream.close();
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (IOException e) {
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // do nothing here
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a file path into a bitmap. If the specified file name is null,
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or cannot be decoded into a bitmap, the function returns null.
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pathName complete path name for the file to be decoded.
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the resulting decoded bitmap, or null if it could not be decoded.
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeFile(String pathName) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return decodeFile(pathName, null);
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a new Bitmap from an InputStream. This InputStream was obtained from
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * resources, which we pass to be able to scale the bitmap accordingly.
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
30311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public static Bitmap decodeResourceStream(Resources res, TypedValue value,
30411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            InputStream is, Rect pad, Options opts) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (opts == null) {
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            opts = new Options();
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (opts.inDensity == 0 && value != null) {
311a53b828635fce8b6b2d3e3377d74d72070056623Dianne Hackborn            final int density = value.density;
31211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            if (density == TypedValue.DENSITY_DEFAULT) {
31311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
31411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            } else if (density != TypedValue.DENSITY_NONE) {
31511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                opts.inDensity = density;
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
31911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (opts.inTargetDensity == 0 && res != null) {
32011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
32111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        }
32211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
32311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return decodeStream(is, pad, opts);
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
32711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Synonym for opening the given resource and calling
32811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * {@link #decodeResourceStream}.
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param res   The resources object containing the image data
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The resource id of the image data
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             image should be completely decoded, or just is size returned.
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image data could not be
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         decoded, or, if opts is non-null, if opts requested only the
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         size be returned (in opts.outWidth and opts.outHeight)
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeResource(Resources res, int id, Options opts) {
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap bm = null;
340650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy        InputStream is = null;
341650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final TypedValue value = new TypedValue();
344650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy            is = res.openRawResource(id, value);
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            bm = decodeResourceStream(res, value, is, null, opts);
347650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy        } catch (Exception e) {
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*  do nothing.
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                If the exception happened on open, bm will be null.
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                If it happened on close, bm is still valid.
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            */
352650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy        } finally {
353650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy            try {
354650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy                if (is != null) is.close();
355650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy            } catch (IOException e) {
356650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy                // Ignore
357650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy            }
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
359650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
362eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
36411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Synonym for {@link #decodeResource(Resources, int, android.graphics.BitmapFactory.Options)}
36511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * will null Options.
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param res The resources object containing the image data
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The resource id of the image data
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image could not be decode.
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeResource(Resources res, int id) {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return decodeResource(res, id, null);
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode an immutable bitmap from the specified byte array.
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param data byte array of compressed image data
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset offset into imageData for where the decoder should begin
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               parsing.
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param length the number of bytes, beginning at offset, to parse
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             image should be completely decoded, or just is size returned.
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image data could not be
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         decoded, or, if opts is non-null, if opts requested only the
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         size be returned (in opts.outWidth and opts.outHeight)
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) {
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((offset | length) < 0 || data.length < offset + length) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return nativeDecodeByteArray(data, offset, length, opts);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
394eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode an immutable bitmap from the specified byte array.
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param data byte array of compressed image data
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset offset into imageData for where the decoder should begin
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               parsing.
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param length the number of bytes, beginning at offset, to parse
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image could not be decode.
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeByteArray(byte[] data, int offset, int length) {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return decodeByteArray(data, offset, length, null);
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
407eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode an input stream into a bitmap. If the input stream is null, or
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cannot be used to decode a bitmap, the function returns null.
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The stream's position will be where ever it was after the encoded data
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was read.
413eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen     *
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param is The input stream that holds the raw data to be decoded into a
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *           bitmap.
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param outPadding If not null, return the padding rect for the bitmap if
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   it exists, otherwise set padding to [-1,-1,-1,-1]. If
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   no bitmap is returned (null) then padding is
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   unchanged.
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             image should be completely decoded, or just is size returned.
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image data could not be
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         decoded, or, if opts is non-null, if opts requested only the
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         size be returned (in opts.outWidth and opts.outHeight)
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we don't throw in this case, thus allowing the caller to only check
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the cache, and not force the image to be decoded.
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (is == null) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
432eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we need mark/reset to work properly
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!is.markSupported()) {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            is = new BufferedInputStream(is, 16 * 1024);
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // so we can call reset() if a given codec gives up after reading up to
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // this many bytes. FIXME: need to find out from the codecs what this
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // value should be.
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        is.mark(1024);
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap  bm;
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (is instanceof AssetManager.AssetInputStream) {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bm = nativeDecodeAsset(((AssetManager.AssetInputStream) is).getAssetInt(),
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    outPadding, opts);
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass some temp storage down to the native code. 1024 is made up,
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // but should be large enough to avoid too many small calls back
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // into is.read(...) This number is not related to the value passed
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to mark(...) above.
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            byte [] tempStorage = null;
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (opts != null)
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tempStorage = opts.inTempStorage;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (tempStorage == null)
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tempStorage = new byte[16 * 1024];
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4627341d7a104b47996445d069a695e155a07184606Dianne Hackborn        return finishDecode(bm, outPadding, opts);
4637341d7a104b47996445d069a695e155a07184606Dianne Hackborn    }
4647341d7a104b47996445d069a695e155a07184606Dianne Hackborn
4657341d7a104b47996445d069a695e155a07184606Dianne Hackborn    private static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) {
46611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (bm == null || opts == null) {
46711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            return bm;
46811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        }
46911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
47011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        final int density = opts.inDensity;
47111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (density == 0) {
47211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            return bm;
47311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        }
47411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
47511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        bm.setDensity(density);
47611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        final int targetDensity = opts.inTargetDensity;
47711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (targetDensity == 0 || density == targetDensity
47811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                || density == opts.inScreenDensity) {
47911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            return bm;
48011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        }
48111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
48211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        byte[] np = bm.getNinePatchChunk();
48311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
48411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (opts.inScaled || isNinePatch) {
48511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            float scale = targetDensity / (float)density;
48611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            // TODO: This is very inefficient and should be done in native by Skia
48711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            final Bitmap oldBitmap = bm;
48811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f),
48911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                    (int) (bm.getHeight() * scale + 0.5f), true);
49011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            oldBitmap.recycle();
49111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
49211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            if (isNinePatch) {
49311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                np = nativeScaleNinePatch(np, scale, outPadding);
49411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                bm.setNinePatchChunk(np);
49511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            }
49611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            bm.setDensity(targetDensity);
49711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        }
49811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5017341d7a104b47996445d069a695e155a07184606Dianne Hackborn
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode an input stream into a bitmap. If the input stream is null, or
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cannot be used to decode a bitmap, the function returns null.
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The stream's position will be where ever it was after the encoded data
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was read.
507eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen     *
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param is The input stream that holds the raw data to be decoded into a
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *           bitmap.
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The decoded bitmap, or null if the image data could not be
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         decoded, or, if opts is non-null, if opts requested only the
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         size be returned (in opts.outWidth and opts.outHeight)
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeStream(InputStream is) {
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return decodeStream(is, null, null);
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a bitmap from the file descriptor. If the bitmap cannot be decoded
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * return null. The position within the descriptor will not be changed when
5217341d7a104b47996445d069a695e155a07184606Dianne Hackborn     * this returns, so the descriptor can be used again as-is.
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param fd The file descriptor containing the bitmap data to decode
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param outPadding If not null, return the padding rect for the bitmap if
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   it exists, otherwise set padding to [-1,-1,-1,-1]. If
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   no bitmap is returned (null) then padding is
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   unchanged.
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param opts null-ok; Options that control downsampling and whether the
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             image should be completely decoded, or just is size returned.
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the decoded bitmap, or null
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
533984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen        try {
534984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen            if (MemoryFile.isMemoryFile(fd)) {
5357bcbd511731e13b9f2778e6aa6c633417d266f5eMarco Nelissen                int mappedlength = MemoryFile.getSize(fd);
536984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen                MemoryFile file = new MemoryFile(fd, mappedlength, "r");
537984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen                InputStream is = file.getInputStream();
5387341d7a104b47996445d069a695e155a07184606Dianne Hackborn                Bitmap bm = decodeStream(is, outPadding, opts);
5397341d7a104b47996445d069a695e155a07184606Dianne Hackborn                return finishDecode(bm, outPadding, opts);
540984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen            }
541984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen        } catch (IOException ex) {
542984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen            // invalid filedescriptor, no need to call nativeDecodeFileDescriptor()
543984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen            return null;
544984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen        }
5457341d7a104b47996445d069a695e155a07184606Dianne Hackborn        Bitmap bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
5467341d7a104b47996445d069a695e155a07184606Dianne Hackborn        return finishDecode(bm, outPadding, opts);
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
548eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decode a bitmap from the file descriptor. If the bitmap cannot be decoded
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * return null. The position within the descriptor will not be changed when
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this returns, so the descriptor can be used again as is.
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param fd The file descriptor containing the bitmap data to decode
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the decoded bitmap, or null
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap decodeFileDescriptor(FileDescriptor fd) {
558984b5df3830fe26a45bee39c7e8dd86714c99ed0Marco Nelissen        return decodeFileDescriptor(fd, null, null);
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
560eb949674fd3b83b706f795fc6b16ab1c66250c93Wei-Ta Chen
561ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed    /**
562ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     * Set the default config used for decoding bitmaps. This config is
563ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     * presented to the codec if the caller did not specify a preferred config
564ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     * in their call to decode...
565ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     *
566ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     * The default value is chosen by the system to best match the device's
567ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     * screen and memory constraints.
568ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     *
569ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     * @param config The preferred config for decoding bitmaps. If null, then
570ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     *               a suitable default is chosen by the system.
571ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     *
572ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     * @hide - only called by the browser at the moment, but should be stable
573ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     *   enough to expose if needed
574ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed     */
575ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed    public static void setDefaultConfig(Bitmap.Config config) {
576ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed        if (config == null) {
577ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed            // pick this for now, as historically it was our default.
578ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed            // However, if we have a smarter algorithm, we can change this.
579ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed            config = Bitmap.Config.RGB_565;
580ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed        }
581ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed        nativeSetDefaultConfig(config.nativeInt);
582ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed    }
583ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed
584ab4a0c164b5a44d5bfd37069cfe499db31e7620cMike Reed    private static native void nativeSetDefaultConfig(int nativeConfig);
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Rect padding, Options opts);
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Rect padding, Options opts);
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts);
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int length, Options opts);
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad);
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
595