diff options
Diffstat (limited to 'graphics/java/android')
| -rw-r--r-- | graphics/java/android/graphics/BitmapFactory.java | 151 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Color.java | 3 | ||||
| -rw-r--r-- | graphics/java/android/graphics/ImageFormat.java | 121 | ||||
| -rw-r--r-- | graphics/java/android/graphics/LargeBitmap.java | 128 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Rect.java | 6 | ||||
| -rw-r--r-- | graphics/java/android/renderscript/Allocation.java | 11 |
6 files changed, 360 insertions, 60 deletions
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index 2313f4cb30a4..6234f2c1c3d1 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -39,7 +39,7 @@ public class BitmapFactory { * the same result from the decoder as if null were passed. */ public Options() { - inDither = true; + inDither = false; inScaled = true; } @@ -69,8 +69,11 @@ public class BitmapFactory { * the decoder will try to pick the best matching config based on the * system's screen depth, and characteristics of the original image such * as if it has per-pixel alpha (requiring a config that also does). + * + * Image are loaded with the {@link Bitmap.Config#ARGB_8888} config by + * default. */ - public Bitmap.Config inPreferredConfig; + public Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888; /** * If dither is true, the decoder will attempt to dither the decoded @@ -452,10 +455,8 @@ public class BitmapFactory { // into is.read(...) This number is not related to the value passed // to mark(...) above. byte [] tempStorage = null; - if (opts != null) - tempStorage = opts.inTempStorage; - if (tempStorage == null) - tempStorage = new byte[16 * 1024]; + if (opts != null) tempStorage = opts.inTempStorage; + if (tempStorage == null) tempStorage = new byte[16 * 1024]; bm = nativeDecodeStream(is, tempStorage, outPadding, opts); } @@ -474,8 +475,7 @@ public class BitmapFactory { bm.setDensity(density); final int targetDensity = opts.inTargetDensity; - if (targetDensity == 0 || density == targetDensity - || density == opts.inScreenDensity) { + if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) { return bm; } @@ -581,6 +581,132 @@ public class BitmapFactory { nativeSetDefaultConfig(config.nativeInt); } + /** + * Create a LargeBitmap from the specified byte array. + * Currently only the Jpeg format is supported. + * + * @param data byte array of compressed image data. + * @param offset offset into data for where the decoder should begin + * parsing. + * @param length the number of bytes, beginning at offset, to parse + * @param isShareable If this is true, then the LargeBitmap may keep a + * shallow reference to the input. If this is false, + * then the LargeBitmap will explicitly make a copy of the + * input data, and keep that. Even if sharing is allowed, + * the implementation may still decide to make a deep + * copy of the input data. If an image is progressively encoded, + * allowing sharing may degrade the decoding speed. + * @return LargeBitmap, or null if the image data could not be decoded. + * @throws IOException if the image format is not supported or can not be decoded. + * @hide + */ + public static LargeBitmap createLargeBitmap(byte[] data, + int offset, int length, boolean isShareable) throws IOException { + if ((offset | length) < 0 || data.length < offset + length) { + throw new ArrayIndexOutOfBoundsException(); + } + return nativeCreateLargeBitmap(data, offset, length, isShareable); + } + + /** + * Create a LargeBitmap from the file descriptor. + * The position within the descriptor will not be changed when + * this returns, so the descriptor can be used again as is. + * Currently only the Jpeg format is supported. + * + * @param fd The file descriptor containing the data to decode + * @param isShareable If this is true, then the LargeBitmap may keep a + * shallow reference to the input. If this is false, + * then the LargeBitmap will explicitly make a copy of the + * input data, and keep that. Even if sharing is allowed, + * the implementation may still decide to make a deep + * copy of the input data. If an image is progressively encoded, + * allowing sharing may degrade the decoding speed. + * @return LargeBitmap, or null if the image data could not be decoded. + * @throws IOException if the image format is not supported or can not be decoded. + * @hide + */ + public static LargeBitmap createLargeBitmap( + FileDescriptor fd, boolean isShareable) throws IOException { + return nativeCreateLargeBitmap(fd, isShareable); + } + + /** + * Create a LargeBitmap from an input stream. + * The stream's position will be where ever it was after the encoded data + * was read. + * Currently only the Jpeg format is supported. + * + * @param is The input stream that holds the raw data to be decoded into a + * LargeBitmap. + * @param isShareable If this is true, then the LargeBitmap may keep a + * shallow reference to the input. If this is false, + * then the LargeBitmap will explicitly make a copy of the + * input data, and keep that. Even if sharing is allowed, + * the implementation may still decide to make a deep + * copy of the input data. If an image is progressively encoded, + * allowing sharing may degrade the decoding speed. + * @return LargeBitmap, or null if the image data could not be decoded. + * @throws IOException if the image format is not supported or can not be decoded. + * @hide + */ + public static LargeBitmap createLargeBitmap(InputStream is, + boolean isShareable) throws IOException { + // we need mark/reset to work properly in JNI + + if (!is.markSupported()) { + is = new BufferedInputStream(is, 16 * 1024); + } + + if (is instanceof AssetManager.AssetInputStream) { + return nativeCreateLargeBitmap( + ((AssetManager.AssetInputStream) is).getAssetInt(), + isShareable); + } else { + // pass some temp storage down to the native code. 1024 is made up, + // but should be large enough to avoid too many small calls back + // into is.read(...). + byte [] tempStorage = new byte[16 * 1024]; + return nativeCreateLargeBitmap(is, tempStorage, isShareable); + } + } + + /** + * Create a LargeBitmap from a file path. + * Currently only the Jpeg format is supported. + * + * @param pathName complete path name for the file to be decoded. + * @param isShareable If this is true, then the LargeBitmap may keep a + * shallow reference to the input. If this is false, + * then the LargeBitmap will explicitly make a copy of the + * input data, and keep that. Even if sharing is allowed, + * the implementation may still decide to make a deep + * copy of the input data. If an image is progressively encoded, + * allowing sharing may degrade the decoding speed. + * @return LargeBitmap, or null if the image data could not be decoded. + * @throws IOException if the image format is not supported or can not be decoded. + * @hide + */ + public static LargeBitmap createLargeBitmap(String pathName, boolean isShareable) + throws IOException { + LargeBitmap bm = null; + InputStream stream = null; + + try { + stream = new FileInputStream(pathName); + bm = createLargeBitmap(stream, isShareable); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + // do nothing here + } + } + } + return bm; + } + private static native void nativeSetDefaultConfig(int nativeConfig); private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage, Rect padding, Options opts); @@ -590,5 +716,14 @@ public class BitmapFactory { private static native Bitmap nativeDecodeByteArray(byte[] data, int offset, int length, Options opts); private static native byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad); + + private static native LargeBitmap nativeCreateLargeBitmap( + byte[] data, int offset, int length, boolean isShareable); + private static native LargeBitmap nativeCreateLargeBitmap( + FileDescriptor fd, boolean isShareable); + private static native LargeBitmap nativeCreateLargeBitmap( + InputStream is, byte[] storage, boolean isShareable); + private static native LargeBitmap nativeCreateLargeBitmap( + int asset, boolean isShareable); } diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java index 5cefaa3b72c6..a50693d2f130 100644 --- a/graphics/java/android/graphics/Color.java +++ b/graphics/java/android/graphics/Color.java @@ -30,7 +30,8 @@ import java.util.Locale; * (green << 8) | blue. Each component ranges between 0..255 with 0 * meaning no contribution for that component, and 255 meaning 100% * contribution. Thus opaque-black would be 0xFF000000 (100% opaque but - * no contributes from red, gree, blue, and opaque-white would be 0xFFFFFFFF + * no contributions from red, green, or blue), and opaque-white would be + * 0xFFFFFFFF */ public class Color { public static final int BLACK = 0xFF000000; diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java index f12637424afa..3f9f961b5a49 100644 --- a/graphics/java/android/graphics/ImageFormat.java +++ b/graphics/java/android/graphics/ImageFormat.java @@ -16,61 +16,84 @@ package android.graphics; -public class ImageFormat -{ - /* these constants are chosen to be binary compatible with - * their previous location in PixelFormat.java */ - - public static final int UNKNOWN = 0; +public class ImageFormat { + /* + * these constants are chosen to be binary compatible with their previous + * location in PixelFormat.java + */ - /** RGB format used for pictures encoded as RGB_565 - * see {@link android.hardware.Camera.Parameters#setPictureFormat(int)}. - */ - public static final int RGB_565 = 4; + public static final int UNKNOWN = 0; - /** - * YCbCr formats, used for video. These are not necessarily supported - * by the hardware. - */ - public static final int NV16 = 0x10; + /** + * RGB format used for pictures encoded as RGB_565 see + * {@link android.hardware.Camera.Parameters#setPictureFormat(int)}. + */ + public static final int RGB_565 = 4; - - /** YCrCb format used for images, which uses the NV21 encoding format. - * This is the default format for camera preview images, when not - * otherwise set with - * {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}. - */ - public static final int NV21 = 0x11; + /** + * Planar 4:2:0 YCrCb format. This format assumes an horizontal stride of 16 + * pixels for all planes and an implicit vertical stride of the image + * height's next multiple of two. + * y_size = stride * ALIGN(height, 2) + * c_size = ALIGN(stride/2, 16) * height + * size = y_size + c_size * 2 + * cr_offset = y_size + * cb_offset = y_size + c_size + * + * Whether this format is supported by the camera hardware can be determined + * by + * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}. + */ + public static final int YV12 = 0x32315659; + /** + * YCbCr format, used for video. Whether this format is supported by the + * camera hardware can be determined by + * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}. + */ + public static final int NV16 = 0x10; - /** YCbCr format used for images, which uses YUYV (YUY2) encoding format. - * This is an alternative format for camera preview images. Whether this - * format is supported by the camera hardware can be determined by - * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}. - */ - public static final int YUY2 = 0x14; + /** + * YCrCb format used for images, which uses the NV21 encoding format. This + * is the default format for camera preview images, when not otherwise set + * with {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}. + */ + public static final int NV21 = 0x11; - - /** - * Encoded formats. These are not necessarily supported by the hardware. - */ - public static final int JPEG = 0x100; + /** + * YCbCr format used for images, which uses YUYV (YUY2) encoding format. + * This is an alternative format for camera preview images. Whether this + * format is supported by the camera hardware can be determined by + * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}. + */ + public static final int YUY2 = 0x14; + /** + * Encoded formats. These are not necessarily supported by the hardware. + */ + public static final int JPEG = 0x100; - /** - * Use this function to retrieve the number of bits per pixel of - * an ImageFormat. - * @param format - * @return the number of bits per pixel of the given format or -1 if the - * format doesn't exist or is not supported. - */ - public static int getBitsPerPixel(int format) { - switch (format) { - case RGB_565: return 16; - case NV16: return 16; - case NV21: return 12; - case YUY2: return 16; - } - return -1; - } + /** + * Use this function to retrieve the number of bits per pixel of an + * ImageFormat. + * + * @param format + * @return the number of bits per pixel of the given format or -1 if the + * format doesn't exist or is not supported. + */ + public static int getBitsPerPixel(int format) { + switch (format) { + case RGB_565: + return 16; + case NV16: + return 16; + case YUY2: + return 16; + case YV12: + return 12; + case NV21: + return 12; + } + return -1; + } } diff --git a/graphics/java/android/graphics/LargeBitmap.java b/graphics/java/android/graphics/LargeBitmap.java new file mode 100644 index 000000000000..6656b1752e91 --- /dev/null +++ b/graphics/java/android/graphics/LargeBitmap.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.DisplayMetrics; + +import java.io.OutputStream; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; + +/** + * LargeBitmap can be used to decode a rectangle region from an image. + * LargeBimap is particularly useful when an original image is large and + * you only need parts of the image. + * + * To create a LargeBitmap, call BitmapFactory.createLargeBitmap(). + * Given a LargeBitmap, users can call decodeRegion() repeatedly + * to get a decoded Bitmap of the specified region. + * @hide + */ +public final class LargeBitmap { + private int mNativeLargeBitmap; + private boolean mRecycled; + + /* Private constructor that must received an already allocated native + large bitmap int (pointer). + + This can be called from JNI code. + */ + private LargeBitmap(int lbm) { + mNativeLargeBitmap = lbm; + mRecycled = false; + } + + /** + * Decodes a rectangle region in the image specified by rect. + * + * @param rect The rectangle that specified the region to be decode. + * @param opts null-ok; Options that control downsampling. + * inPurgeable is not supported. + * @return The decoded bitmap, or null if the image data could not be + * decoded. + */ + public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) { + checkRecycled("decodeRegion called on recycled large bitmap"); + if (rect.left < 0 || rect.top < 0 || rect.right > getWidth() || rect.bottom > getHeight()) + throw new IllegalArgumentException("rectangle is not inside the image"); + return nativeDecodeRegion(mNativeLargeBitmap, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, options); + } + + /** Returns the original image's width */ + public int getWidth() { + checkRecycled("getWidth called on recycled large bitmap"); + return nativeGetWidth(mNativeLargeBitmap); + } + + /** Returns the original image's height */ + public int getHeight() { + checkRecycled("getHeight called on recycled large bitmap"); + return nativeGetHeight(mNativeLargeBitmap); + } + + /** + * Frees up the memory associated with this large bitmap, and mark the + * large bitmap as "dead", meaning it will throw an exception if decodeRegion(), + * getWidth() or getHeight() is called. + * This operation cannot be reversed, so it should only be called if you are + * sure there are no further uses for the large bitmap. This is an advanced call, + * and normally need not be called, since the normal GC process will free up this + * memory when there are no more references to this bitmap. + */ + public void recycle() { + if (!mRecycled) { + nativeClean(mNativeLargeBitmap); + mRecycled = true; + } + } + + /** + * Returns true if this large bitmap has been recycled. + * If so, then it is an error to try use its method. + * + * @return true if the large bitmap has been recycled + */ + public final boolean isRecycled() { + return mRecycled; + } + + /** + * Called by methods that want to throw an exception if the bitmap + * has already been recycled. + */ + private void checkRecycled(String errorMessage) { + if (mRecycled) { + throw new IllegalStateException(errorMessage); + } + } + + protected void finalize() { + recycle(); + } + + private static native Bitmap nativeDecodeRegion(int lbm, + int start_x, int start_y, int width, int height, + BitmapFactory.Options options); + private static native int nativeGetWidth(int lbm); + private static native int nativeGetHeight(int lbm); + private static native void nativeClean(int lbm); +} diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index 98ffb8b4318b..78302244e1c1 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -75,6 +75,7 @@ public final class Rect implements Parcelable { bottom = r.bottom; } + @Override public boolean equals(Object obj) { Rect r = (Rect) obj; if (r != null) { @@ -84,6 +85,7 @@ public final class Rect implements Parcelable { return false; } + @Override public String toString() { StringBuilder sb = new StringBuilder(32); sb.append("Rect("); sb.append(left); sb.append(", "); @@ -351,7 +353,7 @@ public final class Rect implements Parcelable { * rectangle, return true and set this rectangle to that intersection, * otherwise return false and do not change this rectangle. No check is * performed to see if either rectangle is empty. Note: To just test for - * intersection, use intersects() + * intersection, use {@link #intersects(Rect, Rect)}. * * @param left The left side of the rectangle being intersected with this * rectangle @@ -445,7 +447,7 @@ public final class Rect implements Parcelable { /** * Returns true iff the two specified rectangles intersect. In no event are * either of the rectangles modified. To record the intersection, - * use intersect() or setIntersect(). + * use {@link #intersect(Rect)} or {@link #setIntersect(Rect, Rect)}. * * @param a The first rectangle being tested for intersection * @param b The second rectangle being tested for intersection diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 17c0778276f1..b27c7f502e96 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -363,6 +363,17 @@ public class Allocation extends BaseObj { static public Allocation createFromBitmapResourceBoxed(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips) throws IllegalArgumentException { + mBitmapOptions.inPreferredConfig = null; + if (dstFmt == rs.mElement_RGBA_8888) { + mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888; + } else if (dstFmt == rs.mElement_RGB_888) { + mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888; + } else if (dstFmt == rs.mElement_RGBA_4444) { + mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_4444; + } else if (dstFmt == rs.mElement_RGB_565) { + mBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565; + } + Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions); return createFromBitmapBoxed(rs, b, dstFmt, genMips); } |
