/** * Returns a Bitmap decoded from the given {@link InputStream} that is rotated to match any EXIF * data present in the stream and that is downsampled according to the given dimensions and any * provided {@link com.bumptech.glide.load.resource.bitmap.DownsampleStrategy} option. * * @see #decode(InputStream, int, int, Options, DecodeCallbacks) */ public Resource<Bitmap> decode(InputStream is, int outWidth, int outHeight, Options options) throws IOException { return decode(is, outWidth, outHeight, options, EMPTY_CALLBACKS); }
int[] sourceDimensions = getDimensions(is, options, callbacks, bitmapPool); int sourceWidth = sourceDimensions[0]; int sourceHeight = sourceDimensions[1]; calculateScaling( imageType, is, targetHeight, options); calculateConfig( is, decodeFormat, if ((options.inSampleSize == 1 || isKitKatOrGreater) && shouldUsePool(imageType)) { int expectedWidth; int expectedHeight; expectedHeight = targetHeight; } else { float densityMultiplier = isScaling(options) ? (float) options.inTargetDensity / options.inDensity : 1f; int sampleSize = options.inSampleSize; setInBitmap(options, bitmapPool, expectedWidth, expectedHeight); Bitmap downsampled = decodeStream(is, options, callbacks, bitmapPool); callbacks.onDecodeComplete(bitmapPool, downsampled);
private static void releaseOptions(BitmapFactory.Options decodeBitmapOptions) { resetOptions(decodeBitmapOptions); synchronized (OPTIONS_QUEUE) { OPTIONS_QUEUE.offer(decodeBitmapOptions); } }
int outWidth = round(exactScaleFactor * sourceWidth); int outHeight = round(exactScaleFactor * sourceHeight); int[] dimensions = getDimensions(is, options, decodeCallbacks, bitmapPool); options.inTargetDensity = adjustTargetDensityForError(adjustedScaleFactor); options.inDensity = getDensityMultiplier(adjustedScaleFactor); if (isScaling(options)) { options.inScaled = true; } else {
} catch (IllegalArgumentException e) { IOException bitmapAssertionException = newIoExceptionForInBitmapAssertion(e, sourceWidth, sourceHeight, outMimeType, options); if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Failed to decode with inBitmap, trying again without Bitmap re-use", bitmapPool.put(options.inBitmap); options.inBitmap = null; return decodeStream(is, options, callbacks, bitmapPool); } catch (IOException resetException) { throw bitmapAssertionException;
private Bitmap downsampleWithSize(MarkEnforcingInputStream is, RecyclableBufferedInputStream bufferedStream, BitmapFactory.Options options, BitmapPool pool, int inWidth, int inHeight, int sampleSize, DecodeFormat decodeFormat) { // Prior to KitKat, the inBitmap size must exactly match the size of the bitmap we're decoding. Bitmap.Config config = getConfig(is, decodeFormat); options.inSampleSize = sampleSize; options.inPreferredConfig = config; if ((options.inSampleSize == 1 || Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) && shouldUsePool(is)) { int targetWidth = (int) Math.ceil(inWidth / (double) sampleSize); int targetHeight = (int) Math.ceil(inHeight / (double) sampleSize); // BitmapFactory will clear out the Bitmap before writing to it, so getDirty is safe. setInBitmap(options, pool.getDirty(targetWidth, targetHeight, config)); } return decodeStream(is, bufferedStream, options); }
final byte[] bytesForOptions = byteArrayPool.getBytes(); final byte[] bytesForStream = byteArrayPool.getBytes(); final BitmapFactory.Options options = getDefaultOptions(); final int[] inDimens = getDimensions(invalidatingStream, bufferedStream, options); final int inWidth = inDimens[0]; final int inHeight = inDimens[1]; final int sampleSize = getRoundedSampleSize(degreesToRotate, inWidth, inHeight, outWidth, outHeight); downsampleWithSize(invalidatingStream, bufferedStream, options, pool, inWidth, inHeight, sampleSize, decodeFormat); byteArrayPool.releaseBytes(bytesForStream); exceptionStream.release(); releaseOptions(options);
BitmapFactory.Options bitmapFactoryOptions = getDefaultOptions(); bitmapFactoryOptions.inTempStorage = bytesForOptions; Bitmap result = decodeFromWrappedStreams(is, bitmapFactoryOptions, downsampleStrategy, decodeFormat, isHardwareConfigAllowed, requestedWidth, requestedHeight, fixBitmapToRequestedDimensions, callbacks); return BitmapResource.obtain(result, bitmapPool); } finally { releaseOptions(bitmapFactoryOptions); byteArrayPool.put(bytesForOptions);
private static Downsampler buildDownsampler() { List<ImageHeaderParser> parsers = Collections.<ImageHeaderParser>singletonList(new DefaultImageHeaderParser()); DisplayMetrics displayMetrics = new DisplayMetrics(); // XHDPI. displayMetrics.densityDpi = 320; BitmapPool bitmapPool = new BitmapPoolAdapter(); ArrayPool arrayPool = new LruArrayPool(); return new Downsampler(parsers, displayMetrics, bitmapPool, arrayPool); }
/** * A method for getting the dimensions of an image from the given InputStream. * * @param is The InputStream representing the image. * @param options The options to pass to {@link BitmapFactory#decodeStream(java.io.InputStream, * android.graphics.Rect, android.graphics.BitmapFactory.Options)}. * @return an array containing the dimensions of the image in the form {width, height}. */ private static int[] getDimensions(InputStream is, BitmapFactory.Options options, DecodeCallbacks decodeCallbacks, BitmapPool bitmapPool) throws IOException { options.inJustDecodeBounds = true; decodeStream(is, options, decodeCallbacks, bitmapPool); options.inJustDecodeBounds = false; return new int[] { options.outWidth, options.outHeight }; }
int outWidth = round(exactScaleFactor * sourceWidth); int outHeight = round(exactScaleFactor * sourceHeight); int[] dimensions = getDimensions(is, options, decodeCallbacks, bitmapPool); options.inTargetDensity = adjustTargetDensityForError(adjustedScaleFactor); options.inDensity = DENSITY_PRECISION_MULTIPLIER; if (isScaling(options)) { options.inScaled = true; } else {
BitmapFactory.Options bitmapFactoryOptions = getDefaultOptions(); bitmapFactoryOptions.inTempStorage = bytesForOptions; Bitmap result = decodeFromWrappedStreams(is, bitmapFactoryOptions, downsampleStrategy, decodeFormat, isHardwareConfigAllowed, requestedWidth, requestedHeight, fixBitmapToRequestedDimensions, callbacks); return BitmapResource.obtain(result, bitmapPool); } finally { releaseOptions(bitmapFactoryOptions); byteArrayPool.put(bytesForOptions, byte[].class);
} catch (IllegalArgumentException e) { IOException bitmapAssertionException = newIoExceptionForInBitmapAssertion(e, sourceWidth, sourceHeight, outMimeType, options); if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Failed to decode with inBitmap, trying again without Bitmap re-use", bitmapPool.put(options.inBitmap); options.inBitmap = null; return decodeStream(is, options, callbacks, bitmapPool); } catch (IOException resetException) { throw bitmapAssertionException;
new Downsampler( imageHeaderParsers, resources.getDisplayMetrics(),
/** * A method for getting the dimensions of an image from the given InputStream. * * @param is The InputStream representing the image. * @param options The options to pass to * {@link BitmapFactory#decodeStream(InputStream, android.graphics.Rect, * BitmapFactory.Options)}. * @return an array containing the dimensions of the image in the form {width, height}. */ public int[] getDimensions(MarkEnforcingInputStream is, RecyclableBufferedInputStream bufferedStream, BitmapFactory.Options options) { options.inJustDecodeBounds = true; decodeStream(is, bufferedStream, options); options.inJustDecodeBounds = false; return new int[] { options.outWidth, options.outHeight }; }
int[] sourceDimensions = getDimensions(is, options, callbacks, bitmapPool); int sourceWidth = sourceDimensions[0]; int sourceHeight = sourceDimensions[1]; calculateScaling( imageType, is, targetHeight, options); calculateConfig( is, decodeFormat, if ((options.inSampleSize == 1 || isKitKatOrGreater) && shouldUsePool(imageType)) { int expectedWidth; int expectedHeight; expectedHeight = targetHeight; } else { float densityMultiplier = isScaling(options) ? (float) options.inTargetDensity / options.inDensity : 1f; int sampleSize = options.inSampleSize; setInBitmap(options, bitmapPool, expectedWidth, expectedHeight); Bitmap downsampled = decodeStream(is, options, callbacks, bitmapPool); callbacks.onDecodeComplete(bitmapPool, downsampled);
@Override public Resource<Bitmap> decode(@NonNull ByteBuffer source, int width, int height, @NonNull Options options) throws IOException { InputStream is = ByteBufferUtil.toStream(source); return downsampler.decode(is, width, height, options); } }
private static synchronized BitmapFactory.Options getDefaultOptions() { BitmapFactory.Options decodeBitmapOptions; synchronized (OPTIONS_QUEUE) { decodeBitmapOptions = OPTIONS_QUEUE.poll(); } if (decodeBitmapOptions == null) { decodeBitmapOptions = new BitmapFactory.Options(); resetOptions(decodeBitmapOptions); } return decodeBitmapOptions; }
registry.register(new DefaultImageHeaderParser()); Downsampler downsampler = new Downsampler(registry.getImageHeaderParsers(), resources.getDisplayMetrics(), bitmapPool, arrayPool);
/** * A method for getting the dimensions of an image from the given InputStream. * * @param is The InputStream representing the image. * @param options The options to pass to {@link BitmapFactory#decodeStream(java.io.InputStream, * android.graphics.Rect, android.graphics.BitmapFactory.Options)}. * @return an array containing the dimensions of the image in the form {width, height}. */ private static int[] getDimensions(InputStream is, BitmapFactory.Options options, DecodeCallbacks decodeCallbacks, BitmapPool bitmapPool) throws IOException { options.inJustDecodeBounds = true; decodeStream(is, options, decodeCallbacks, bitmapPool); options.inJustDecodeBounds = false; return new int[] { options.outWidth, options.outHeight }; }