1841a502864d307341945eae62569b92cada93e75Sunny Goyalpackage com.android.wallpaperpicker.common; 2841a502864d307341945eae62569b92cada93e75Sunny Goyal 3841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.content.Context; 4841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.content.res.Resources; 5841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.graphics.Bitmap; 6841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.graphics.BitmapFactory; 7841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.graphics.BitmapRegionDecoder; 8841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.graphics.Canvas; 9841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.graphics.Matrix; 10841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.graphics.Paint; 11841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.graphics.Point; 12841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.graphics.Rect; 13841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.graphics.RectF; 14841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.net.Uri; 15841a502864d307341945eae62569b92cada93e75Sunny Goyalimport android.util.Log; 16841a502864d307341945eae62569b92cada93e75Sunny Goyal 17841a502864d307341945eae62569b92cada93e75Sunny Goyalimport com.android.gallery3d.common.ExifOrientation; 18841a502864d307341945eae62569b92cada93e75Sunny Goyalimport com.android.gallery3d.common.Utils; 19841a502864d307341945eae62569b92cada93e75Sunny Goyal 20841a502864d307341945eae62569b92cada93e75Sunny Goyalimport java.io.BufferedInputStream; 21841a502864d307341945eae62569b92cada93e75Sunny Goyalimport java.io.ByteArrayInputStream; 22841a502864d307341945eae62569b92cada93e75Sunny Goyalimport java.io.IOException; 23841a502864d307341945eae62569b92cada93e75Sunny Goyalimport java.io.InputStream; 24841a502864d307341945eae62569b92cada93e75Sunny Goyal 25841a502864d307341945eae62569b92cada93e75Sunny Goyal/** 26841a502864d307341945eae62569b92cada93e75Sunny Goyal * An abstraction over input stream creation. Also contains some utility methods 27841a502864d307341945eae62569b92cada93e75Sunny Goyal * for various bitmap operations. 28841a502864d307341945eae62569b92cada93e75Sunny Goyal */ 29841a502864d307341945eae62569b92cada93e75Sunny Goyalpublic abstract class InputStreamProvider { 30841a502864d307341945eae62569b92cada93e75Sunny Goyal 31841a502864d307341945eae62569b92cada93e75Sunny Goyal private static final String TAG = "InputStreamProvider"; 32841a502864d307341945eae62569b92cada93e75Sunny Goyal 33841a502864d307341945eae62569b92cada93e75Sunny Goyal /** 34841a502864d307341945eae62569b92cada93e75Sunny Goyal * Tries to create a new stream or returns null on failure. 35841a502864d307341945eae62569b92cada93e75Sunny Goyal */ 36841a502864d307341945eae62569b92cada93e75Sunny Goyal public InputStream newStream() { 37841a502864d307341945eae62569b92cada93e75Sunny Goyal try { 38841a502864d307341945eae62569b92cada93e75Sunny Goyal return newStreamNotNull(); 39841a502864d307341945eae62569b92cada93e75Sunny Goyal } catch (IOException e) { 40841a502864d307341945eae62569b92cada93e75Sunny Goyal return null; 41841a502864d307341945eae62569b92cada93e75Sunny Goyal } 42841a502864d307341945eae62569b92cada93e75Sunny Goyal } 43841a502864d307341945eae62569b92cada93e75Sunny Goyal 44841a502864d307341945eae62569b92cada93e75Sunny Goyal /** 45841a502864d307341945eae62569b92cada93e75Sunny Goyal * Tries to create a new stream or throws an exception on failure. 46841a502864d307341945eae62569b92cada93e75Sunny Goyal */ 47841a502864d307341945eae62569b92cada93e75Sunny Goyal public abstract InputStream newStreamNotNull() throws IOException; 48841a502864d307341945eae62569b92cada93e75Sunny Goyal 49841a502864d307341945eae62569b92cada93e75Sunny Goyal /** 50841a502864d307341945eae62569b92cada93e75Sunny Goyal * Returns the size of the image, if the stream represents an image. 51841a502864d307341945eae62569b92cada93e75Sunny Goyal */ 52841a502864d307341945eae62569b92cada93e75Sunny Goyal public Point getImageBounds() { 53841a502864d307341945eae62569b92cada93e75Sunny Goyal InputStream is = newStream(); 54841a502864d307341945eae62569b92cada93e75Sunny Goyal if (is != null) { 55841a502864d307341945eae62569b92cada93e75Sunny Goyal BitmapFactory.Options options = new BitmapFactory.Options(); 56841a502864d307341945eae62569b92cada93e75Sunny Goyal options.inJustDecodeBounds = true; 57841a502864d307341945eae62569b92cada93e75Sunny Goyal BitmapFactory.decodeStream(is, null, options); 58841a502864d307341945eae62569b92cada93e75Sunny Goyal Utils.closeSilently(is); 59841a502864d307341945eae62569b92cada93e75Sunny Goyal if (options.outWidth != 0 && options.outHeight != 0) { 60841a502864d307341945eae62569b92cada93e75Sunny Goyal return new Point(options.outWidth, options.outHeight); 61841a502864d307341945eae62569b92cada93e75Sunny Goyal } 62841a502864d307341945eae62569b92cada93e75Sunny Goyal } 63841a502864d307341945eae62569b92cada93e75Sunny Goyal return null; 64841a502864d307341945eae62569b92cada93e75Sunny Goyal } 65841a502864d307341945eae62569b92cada93e75Sunny Goyal 66841a502864d307341945eae62569b92cada93e75Sunny Goyal public Bitmap readCroppedBitmap(RectF cropBounds, int outWidth, int outHeight, int rotation) { 67841a502864d307341945eae62569b92cada93e75Sunny Goyal // Find crop bounds (scaled to original image size) 68841a502864d307341945eae62569b92cada93e75Sunny Goyal Rect roundedTrueCrop = new Rect(); 69841a502864d307341945eae62569b92cada93e75Sunny Goyal Matrix rotateMatrix = new Matrix(); 70841a502864d307341945eae62569b92cada93e75Sunny Goyal Point bounds = getImageBounds(); 71841a502864d307341945eae62569b92cada93e75Sunny Goyal if (bounds == null) { 72841a502864d307341945eae62569b92cada93e75Sunny Goyal Log.w(TAG, "cannot get bounds for image"); 73841a502864d307341945eae62569b92cada93e75Sunny Goyal return null; 74841a502864d307341945eae62569b92cada93e75Sunny Goyal } 75841a502864d307341945eae62569b92cada93e75Sunny Goyal 76841a502864d307341945eae62569b92cada93e75Sunny Goyal if (rotation > 0) { 77841a502864d307341945eae62569b92cada93e75Sunny Goyal rotateMatrix.setRotate(rotation); 78841a502864d307341945eae62569b92cada93e75Sunny Goyal 79841a502864d307341945eae62569b92cada93e75Sunny Goyal Matrix inverseRotateMatrix = new Matrix(); 80841a502864d307341945eae62569b92cada93e75Sunny Goyal inverseRotateMatrix.setRotate(-rotation); 81841a502864d307341945eae62569b92cada93e75Sunny Goyal 82841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.roundOut(roundedTrueCrop); 83841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.set(roundedTrueCrop); 84841a502864d307341945eae62569b92cada93e75Sunny Goyal 85841a502864d307341945eae62569b92cada93e75Sunny Goyal float[] rotatedBounds = new float[] { bounds.x, bounds.y }; 86841a502864d307341945eae62569b92cada93e75Sunny Goyal rotateMatrix.mapPoints(rotatedBounds); 87841a502864d307341945eae62569b92cada93e75Sunny Goyal rotatedBounds[0] = Math.abs(rotatedBounds[0]); 88841a502864d307341945eae62569b92cada93e75Sunny Goyal rotatedBounds[1] = Math.abs(rotatedBounds[1]); 89841a502864d307341945eae62569b92cada93e75Sunny Goyal 90841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.offset(-rotatedBounds[0]/2, -rotatedBounds[1]/2); 91841a502864d307341945eae62569b92cada93e75Sunny Goyal inverseRotateMatrix.mapRect(cropBounds); 92841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.offset(bounds.x/2, bounds.y/2); 93841a502864d307341945eae62569b92cada93e75Sunny Goyal } 94841a502864d307341945eae62569b92cada93e75Sunny Goyal 95841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.roundOut(roundedTrueCrop); 96841a502864d307341945eae62569b92cada93e75Sunny Goyal if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) { 97841a502864d307341945eae62569b92cada93e75Sunny Goyal Log.w(TAG, "crop has bad values for full size image"); 98841a502864d307341945eae62569b92cada93e75Sunny Goyal return null; 99841a502864d307341945eae62569b92cada93e75Sunny Goyal } 100841a502864d307341945eae62569b92cada93e75Sunny Goyal 101841a502864d307341945eae62569b92cada93e75Sunny Goyal // See how much we're reducing the size of the image 102841a502864d307341945eae62569b92cada93e75Sunny Goyal int scaleDownSampleSize = Math.max(1, Math.min(roundedTrueCrop.width() / outWidth, 103841a502864d307341945eae62569b92cada93e75Sunny Goyal roundedTrueCrop.height() / outHeight)); 104841a502864d307341945eae62569b92cada93e75Sunny Goyal // Attempt to open a region decoder 105841a502864d307341945eae62569b92cada93e75Sunny Goyal InputStream is = null; 106841a502864d307341945eae62569b92cada93e75Sunny Goyal BitmapRegionDecoder decoder = null; 107841a502864d307341945eae62569b92cada93e75Sunny Goyal try { 108841a502864d307341945eae62569b92cada93e75Sunny Goyal is = newStreamNotNull(); 109841a502864d307341945eae62569b92cada93e75Sunny Goyal decoder = BitmapRegionDecoder.newInstance(is, false); 110841a502864d307341945eae62569b92cada93e75Sunny Goyal } catch (IOException e) { 111841a502864d307341945eae62569b92cada93e75Sunny Goyal Log.w(TAG, "cannot open region decoder", e); 112841a502864d307341945eae62569b92cada93e75Sunny Goyal } finally { 113841a502864d307341945eae62569b92cada93e75Sunny Goyal Utils.closeSilently(is); 114841a502864d307341945eae62569b92cada93e75Sunny Goyal is = null; 115841a502864d307341945eae62569b92cada93e75Sunny Goyal } 116841a502864d307341945eae62569b92cada93e75Sunny Goyal 117841a502864d307341945eae62569b92cada93e75Sunny Goyal Bitmap crop = null; 118841a502864d307341945eae62569b92cada93e75Sunny Goyal if (decoder != null) { 119841a502864d307341945eae62569b92cada93e75Sunny Goyal // Do region decoding to get crop bitmap 120841a502864d307341945eae62569b92cada93e75Sunny Goyal BitmapFactory.Options options = new BitmapFactory.Options(); 121841a502864d307341945eae62569b92cada93e75Sunny Goyal if (scaleDownSampleSize > 1) { 122841a502864d307341945eae62569b92cada93e75Sunny Goyal options.inSampleSize = scaleDownSampleSize; 123841a502864d307341945eae62569b92cada93e75Sunny Goyal } 124841a502864d307341945eae62569b92cada93e75Sunny Goyal crop = decoder.decodeRegion(roundedTrueCrop, options); 125841a502864d307341945eae62569b92cada93e75Sunny Goyal decoder.recycle(); 126841a502864d307341945eae62569b92cada93e75Sunny Goyal } 127841a502864d307341945eae62569b92cada93e75Sunny Goyal 128841a502864d307341945eae62569b92cada93e75Sunny Goyal if (crop == null) { 129841a502864d307341945eae62569b92cada93e75Sunny Goyal // BitmapRegionDecoder has failed, try to crop in-memory 130841a502864d307341945eae62569b92cada93e75Sunny Goyal is = newStream(); 131841a502864d307341945eae62569b92cada93e75Sunny Goyal Bitmap fullSize = null; 132841a502864d307341945eae62569b92cada93e75Sunny Goyal if (is != null) { 133841a502864d307341945eae62569b92cada93e75Sunny Goyal BitmapFactory.Options options = new BitmapFactory.Options(); 134841a502864d307341945eae62569b92cada93e75Sunny Goyal if (scaleDownSampleSize > 1) { 135841a502864d307341945eae62569b92cada93e75Sunny Goyal options.inSampleSize = scaleDownSampleSize; 136841a502864d307341945eae62569b92cada93e75Sunny Goyal } 137841a502864d307341945eae62569b92cada93e75Sunny Goyal fullSize = BitmapFactory.decodeStream(is, null, options); 138841a502864d307341945eae62569b92cada93e75Sunny Goyal Utils.closeSilently(is); 139841a502864d307341945eae62569b92cada93e75Sunny Goyal } 140841a502864d307341945eae62569b92cada93e75Sunny Goyal if (fullSize != null) { 141841a502864d307341945eae62569b92cada93e75Sunny Goyal // Find out the true sample size that was used by the decoder 142841a502864d307341945eae62569b92cada93e75Sunny Goyal scaleDownSampleSize = bounds.x / fullSize.getWidth(); 143841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.left /= scaleDownSampleSize; 144841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.top /= scaleDownSampleSize; 145841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.bottom /= scaleDownSampleSize; 146841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.right /= scaleDownSampleSize; 147841a502864d307341945eae62569b92cada93e75Sunny Goyal cropBounds.roundOut(roundedTrueCrop); 148841a502864d307341945eae62569b92cada93e75Sunny Goyal 149841a502864d307341945eae62569b92cada93e75Sunny Goyal // Adjust values to account for issues related to rounding 150841a502864d307341945eae62569b92cada93e75Sunny Goyal if (roundedTrueCrop.width() > fullSize.getWidth()) { 151841a502864d307341945eae62569b92cada93e75Sunny Goyal // Adjust the width 152841a502864d307341945eae62569b92cada93e75Sunny Goyal roundedTrueCrop.right = roundedTrueCrop.left + fullSize.getWidth(); 153841a502864d307341945eae62569b92cada93e75Sunny Goyal } 154841a502864d307341945eae62569b92cada93e75Sunny Goyal if (roundedTrueCrop.right > fullSize.getWidth()) { 155841a502864d307341945eae62569b92cada93e75Sunny Goyal // Adjust the left and right values. 156841a502864d307341945eae62569b92cada93e75Sunny Goyal roundedTrueCrop.offset(-(roundedTrueCrop.right - fullSize.getWidth()), 0); 157841a502864d307341945eae62569b92cada93e75Sunny Goyal } 158841a502864d307341945eae62569b92cada93e75Sunny Goyal if (roundedTrueCrop.height() > fullSize.getHeight()) { 159841a502864d307341945eae62569b92cada93e75Sunny Goyal // Adjust the height 160841a502864d307341945eae62569b92cada93e75Sunny Goyal roundedTrueCrop.bottom = roundedTrueCrop.top + fullSize.getHeight(); 161841a502864d307341945eae62569b92cada93e75Sunny Goyal } 162841a502864d307341945eae62569b92cada93e75Sunny Goyal if (roundedTrueCrop.bottom > fullSize.getHeight()) { 163841a502864d307341945eae62569b92cada93e75Sunny Goyal // Adjust the top and bottom values. 164841a502864d307341945eae62569b92cada93e75Sunny Goyal roundedTrueCrop.offset(0, -(roundedTrueCrop.bottom - fullSize.getHeight())); 165841a502864d307341945eae62569b92cada93e75Sunny Goyal } 166841a502864d307341945eae62569b92cada93e75Sunny Goyal 167841a502864d307341945eae62569b92cada93e75Sunny Goyal crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left, 168841a502864d307341945eae62569b92cada93e75Sunny Goyal roundedTrueCrop.top, roundedTrueCrop.width(), 169841a502864d307341945eae62569b92cada93e75Sunny Goyal roundedTrueCrop.height()); 170841a502864d307341945eae62569b92cada93e75Sunny Goyal } 171841a502864d307341945eae62569b92cada93e75Sunny Goyal } 172841a502864d307341945eae62569b92cada93e75Sunny Goyal 173841a502864d307341945eae62569b92cada93e75Sunny Goyal if (crop == null) { 174841a502864d307341945eae62569b92cada93e75Sunny Goyal return null; 175841a502864d307341945eae62569b92cada93e75Sunny Goyal } 176841a502864d307341945eae62569b92cada93e75Sunny Goyal if (outWidth > 0 && outHeight > 0 || rotation > 0) { 177841a502864d307341945eae62569b92cada93e75Sunny Goyal float[] dimsAfter = new float[] { crop.getWidth(), crop.getHeight() }; 178841a502864d307341945eae62569b92cada93e75Sunny Goyal rotateMatrix.mapPoints(dimsAfter); 179841a502864d307341945eae62569b92cada93e75Sunny Goyal dimsAfter[0] = Math.abs(dimsAfter[0]); 180841a502864d307341945eae62569b92cada93e75Sunny Goyal dimsAfter[1] = Math.abs(dimsAfter[1]); 181841a502864d307341945eae62569b92cada93e75Sunny Goyal 182841a502864d307341945eae62569b92cada93e75Sunny Goyal if (!(outWidth > 0 && outHeight > 0)) { 183841a502864d307341945eae62569b92cada93e75Sunny Goyal outWidth = Math.round(dimsAfter[0]); 184841a502864d307341945eae62569b92cada93e75Sunny Goyal outHeight = Math.round(dimsAfter[1]); 185841a502864d307341945eae62569b92cada93e75Sunny Goyal } 186841a502864d307341945eae62569b92cada93e75Sunny Goyal 187841a502864d307341945eae62569b92cada93e75Sunny Goyal RectF cropRect = new RectF(0, 0, dimsAfter[0], dimsAfter[1]); 188841a502864d307341945eae62569b92cada93e75Sunny Goyal RectF returnRect = new RectF(0, 0, outWidth, outHeight); 189841a502864d307341945eae62569b92cada93e75Sunny Goyal 190841a502864d307341945eae62569b92cada93e75Sunny Goyal Matrix m = new Matrix(); 191841a502864d307341945eae62569b92cada93e75Sunny Goyal if (rotation == 0) { 192841a502864d307341945eae62569b92cada93e75Sunny Goyal m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL); 193841a502864d307341945eae62569b92cada93e75Sunny Goyal } else { 194841a502864d307341945eae62569b92cada93e75Sunny Goyal Matrix m1 = new Matrix(); 195841a502864d307341945eae62569b92cada93e75Sunny Goyal m1.setTranslate(-crop.getWidth() / 2f, -crop.getHeight() / 2f); 196841a502864d307341945eae62569b92cada93e75Sunny Goyal Matrix m2 = new Matrix(); 197841a502864d307341945eae62569b92cada93e75Sunny Goyal m2.setRotate(rotation); 198841a502864d307341945eae62569b92cada93e75Sunny Goyal Matrix m3 = new Matrix(); 199841a502864d307341945eae62569b92cada93e75Sunny Goyal m3.setTranslate(dimsAfter[0] / 2f, dimsAfter[1] / 2f); 200841a502864d307341945eae62569b92cada93e75Sunny Goyal Matrix m4 = new Matrix(); 201841a502864d307341945eae62569b92cada93e75Sunny Goyal m4.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL); 202841a502864d307341945eae62569b92cada93e75Sunny Goyal 203841a502864d307341945eae62569b92cada93e75Sunny Goyal Matrix c1 = new Matrix(); 204841a502864d307341945eae62569b92cada93e75Sunny Goyal c1.setConcat(m2, m1); 205841a502864d307341945eae62569b92cada93e75Sunny Goyal Matrix c2 = new Matrix(); 206841a502864d307341945eae62569b92cada93e75Sunny Goyal c2.setConcat(m4, m3); 207841a502864d307341945eae62569b92cada93e75Sunny Goyal m.setConcat(c2, c1); 208841a502864d307341945eae62569b92cada93e75Sunny Goyal } 209841a502864d307341945eae62569b92cada93e75Sunny Goyal 210841a502864d307341945eae62569b92cada93e75Sunny Goyal Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(), 211841a502864d307341945eae62569b92cada93e75Sunny Goyal (int) returnRect.height(), Bitmap.Config.ARGB_8888); 212841a502864d307341945eae62569b92cada93e75Sunny Goyal if (tmp != null) { 213841a502864d307341945eae62569b92cada93e75Sunny Goyal Canvas c = new Canvas(tmp); 214841a502864d307341945eae62569b92cada93e75Sunny Goyal Paint p = new Paint(); 215841a502864d307341945eae62569b92cada93e75Sunny Goyal p.setFilterBitmap(true); 216841a502864d307341945eae62569b92cada93e75Sunny Goyal c.drawBitmap(crop, m, p); 217841a502864d307341945eae62569b92cada93e75Sunny Goyal crop = tmp; 218841a502864d307341945eae62569b92cada93e75Sunny Goyal } 219841a502864d307341945eae62569b92cada93e75Sunny Goyal } 220841a502864d307341945eae62569b92cada93e75Sunny Goyal return crop; 221841a502864d307341945eae62569b92cada93e75Sunny Goyal } 222841a502864d307341945eae62569b92cada93e75Sunny Goyal 223841a502864d307341945eae62569b92cada93e75Sunny Goyal public int getRotationFromExif(Context context) { 224841a502864d307341945eae62569b92cada93e75Sunny Goyal InputStream is = null; 225841a502864d307341945eae62569b92cada93e75Sunny Goyal try { 226841a502864d307341945eae62569b92cada93e75Sunny Goyal is = newStreamNotNull(); 227841a502864d307341945eae62569b92cada93e75Sunny Goyal return ExifOrientation.readRotation(new BufferedInputStream(is), context); 228841a502864d307341945eae62569b92cada93e75Sunny Goyal } catch (IOException | NullPointerException e) { 229841a502864d307341945eae62569b92cada93e75Sunny Goyal Log.w(TAG, "Getting exif data failed", e); 230841a502864d307341945eae62569b92cada93e75Sunny Goyal } finally { 231841a502864d307341945eae62569b92cada93e75Sunny Goyal Utils.closeSilently(is); 232841a502864d307341945eae62569b92cada93e75Sunny Goyal } 233841a502864d307341945eae62569b92cada93e75Sunny Goyal return 0; 234841a502864d307341945eae62569b92cada93e75Sunny Goyal } 235841a502864d307341945eae62569b92cada93e75Sunny Goyal 236841a502864d307341945eae62569b92cada93e75Sunny Goyal public static InputStreamProvider fromUri(final Context context, final Uri uri) { 237841a502864d307341945eae62569b92cada93e75Sunny Goyal return new InputStreamProvider() { 238841a502864d307341945eae62569b92cada93e75Sunny Goyal @Override 239841a502864d307341945eae62569b92cada93e75Sunny Goyal public InputStream newStreamNotNull() throws IOException { 240841a502864d307341945eae62569b92cada93e75Sunny Goyal return new BufferedInputStream(context.getContentResolver().openInputStream(uri)); 241841a502864d307341945eae62569b92cada93e75Sunny Goyal } 242841a502864d307341945eae62569b92cada93e75Sunny Goyal }; 243841a502864d307341945eae62569b92cada93e75Sunny Goyal } 244841a502864d307341945eae62569b92cada93e75Sunny Goyal 245841a502864d307341945eae62569b92cada93e75Sunny Goyal public static InputStreamProvider fromResource(final Resources resources, final int resId) { 246841a502864d307341945eae62569b92cada93e75Sunny Goyal return new InputStreamProvider() { 247841a502864d307341945eae62569b92cada93e75Sunny Goyal @Override 248841a502864d307341945eae62569b92cada93e75Sunny Goyal public InputStream newStreamNotNull() { 249841a502864d307341945eae62569b92cada93e75Sunny Goyal return new BufferedInputStream(resources.openRawResource(resId)); 250841a502864d307341945eae62569b92cada93e75Sunny Goyal } 251841a502864d307341945eae62569b92cada93e75Sunny Goyal }; 252841a502864d307341945eae62569b92cada93e75Sunny Goyal } 253841a502864d307341945eae62569b92cada93e75Sunny Goyal 254841a502864d307341945eae62569b92cada93e75Sunny Goyal public static InputStreamProvider fromBytes(final byte[] bytes) { 255841a502864d307341945eae62569b92cada93e75Sunny Goyal return new InputStreamProvider() { 256841a502864d307341945eae62569b92cada93e75Sunny Goyal @Override 257841a502864d307341945eae62569b92cada93e75Sunny Goyal public InputStream newStreamNotNull() { 258841a502864d307341945eae62569b92cada93e75Sunny Goyal return new BufferedInputStream(new ByteArrayInputStream(bytes)); 259841a502864d307341945eae62569b92cada93e75Sunny Goyal } 260841a502864d307341945eae62569b92cada93e75Sunny Goyal }; 261841a502864d307341945eae62569b92cada93e75Sunny Goyal } 262841a502864d307341945eae62569b92cada93e75Sunny Goyal 263841a502864d307341945eae62569b92cada93e75Sunny Goyal} 264