private static Bitmap decodeResourcePreP(Resources resources, int id, Request request) { final BitmapFactory.Options options = createBitmapOptions(request); if (requiresInSampleSize(options)) { BitmapFactory.decodeResource(resources, id, options); calculateInSampleSize(request.targetWidth, request.targetHeight, checkNotNull(options, "options == null"), request); } return BitmapFactory.decodeResource(resources, id, options); }
@RequiresApi(28) private static Bitmap decodeResourceP(Context context, final Request request) throws IOException { ImageDecoder.Source imageSource = ImageDecoder.createSource(context.getResources(), request.resourceId); return decodeImageSource(imageSource, request); }
@Override public void load(@NonNull Picasso picasso, @NonNull Request request, @NonNull Callback callback) { boolean signaledCallback = false; try { Bitmap bitmap = decodeResource(context, request); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK)); } catch (Exception e) { if (!signaledCallback) { callback.onError(e); } } } }
static Bitmap decodeResource(Context context, Request request) throws IOException { if (SDK_INT >= 28) { return decodeResourceP(context, request); } Resources resources = Utils.getResources(context, request); int id = Utils.getResourceId(resources, request); return decodeResourcePreP(resources, id, request); }
/** * Decode a byte stream into a Bitmap. This method will take into account additional information * about the supplied request in order to do the decoding efficiently (such as through leveraging * {@code inSampleSize}). */ static Bitmap decodeStream(Source source, Request request) throws IOException { ExceptionCatchingSource exceptionCatchingSource = new ExceptionCatchingSource(source); BufferedSource bufferedSource = Okio.buffer(exceptionCatchingSource); Bitmap bitmap = SDK_INT >= 28 ? decodeStreamP(request, bufferedSource) : decodeStreamPreP(request, bufferedSource); exceptionCatchingSource.throwIfCaught(); return bitmap; }
if (!isVideo && picassoKind == FULL) { Source source = getSource(requestUri); Bitmap bitmap = decodeStream(source, request); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK, exifOrientation)); checkNotNull(createBitmapOptions(request), "options == null"); options.inJustDecodeBounds = true; calculateInSampleSize(request.targetWidth, request.targetHeight, picassoKind.width, picassoKind.height, options, request); Bitmap bitmap = decodeStream(source, request); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK, exifOrientation));
static void calculateInSampleSize(int reqWidth, int reqHeight, @NonNull BitmapFactory.Options options, Request request) { calculateInSampleSize(reqWidth, reqHeight, options.outWidth, options.outHeight, options, request); }
@Test public void nullBitmapOptionsIfNoResizingOrPurgeable() { // No resize must return no bitmap options final Request noResize = new Request.Builder(URI_1).build(); final BitmapFactory.Options noResizeOptions = createBitmapOptions(noResize); assertThat(noResizeOptions).isNull(); }
@Test public void requiresComputeInSampleSize() { assertThat(requiresInSampleSize(null)).isFalse(); final BitmapFactory.Options defaultOptions = new BitmapFactory.Options(); assertThat(requiresInSampleSize(defaultOptions)).isFalse(); final BitmapFactory.Options justBounds = new BitmapFactory.Options(); justBounds.inJustDecodeBounds = true; assertThat(requiresInSampleSize(justBounds)).isTrue(); }
@Override public void load(@NonNull Picasso picasso, @NonNull Request request, @NonNull Callback callback) { boolean signaledCallback = false; try { Uri requestUri = checkNotNull(request.uri, "request.uri == null"); Source source = getSource(requestUri); Bitmap bitmap = decodeStream(source, request); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK)); } catch (Exception e) { if (!signaledCallback) { callback.onError(e); } } }
@Test public void calculateInSampleSizeNoResize() { final BitmapFactory.Options options = new BitmapFactory.Options(); Request data = new Request.Builder(URI_1).build(); calculateInSampleSize(100, 100, 150, 150, options, data); assertThat(options.inSampleSize).isEqualTo(1); }
@Test public void inPurgeableIfInPurgeable() { final Request request = new Request.Builder(URI_1).purgeable().build(); final BitmapFactory.Options options = createBitmapOptions(request); assertThat(options).isNotNull(); assertThat(options.inPurgeable).isTrue(); assertThat(options.inInputShareable).isTrue(); assertThat(options.inJustDecodeBounds).isFalse(); }
@Override public void load(@NonNull Picasso picasso, @NonNull Request request, @NonNull Callback callback) { boolean signaledCallback = false; try { Uri requestUri = checkNotNull(request.uri, "request.uri == null"); Source source = getSource(requestUri); Bitmap bitmap = decodeStream(source, request); int exifRotation = getExifOrientation(requestUri); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK, exifRotation)); } catch (Exception e) { if (!signaledCallback) { callback.onError(e); } } }
boolean isWebPFile = Utils.isWebPFile(bufferedSource); boolean isPurgeable = request.purgeable && SDK_INT < Build.VERSION_CODES.LOLLIPOP; BitmapFactory.Options options = createBitmapOptions(request); boolean calculateSize = requiresInSampleSize(options); if (calculateSize) { BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); calculateInSampleSize(request.targetWidth, request.targetHeight, checkNotNull(options, "options == null"), request); if (calculateSize) { BitmapFactory.decodeStream(bufferedSource.peek().inputStream(), null, options); calculateInSampleSize(request.targetWidth, request.targetHeight, checkNotNull(options, "options == null"), request);
@Test public void calculateInSampleSizeResize() { final BitmapFactory.Options options = new BitmapFactory.Options(); Request data = new Request.Builder(URI_1).build(); calculateInSampleSize(100, 100, 200, 200, options, data); assertThat(options.inSampleSize).isEqualTo(2); }
@Test public void createWithConfigAndNotInJustDecodeBoundsOrInPurgeable() { // Given a config, must return bitmap options and false inJustDecodeBounds/inPurgeable final Request config = new Request.Builder(URI_1).config(RGB_565).build(); final BitmapFactory.Options configOptions = createBitmapOptions(config); assertThat(configOptions).isNotNull(); assertThat(configOptions.inJustDecodeBounds).isFalse(); assertThat(configOptions.inPurgeable).isFalse(); assertThat(configOptions.inInputShareable).isFalse(); } }
@Override public void load(@NonNull Picasso picasso, @NonNull Request request, @NonNull Callback callback) { boolean signaledCallback = false; try { Uri requestUri = checkNotNull(request.uri, "request.uri == null"); Source source = getSource(requestUri); Bitmap bitmap = decodeStream(source, request); int exifRotation = getExifOrientation(requestUri); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK, exifRotation)); } catch (Exception e) { if (!signaledCallback) { callback.onError(e); } } }
@RequiresApi(28) @SuppressLint("Override") private static Bitmap decodeStreamP(Request request, BufferedSource bufferedSource) throws IOException { ImageDecoder.Source imageSource = ImageDecoder.createSource(ByteBuffer.wrap(bufferedSource.readByteArray())); return decodeImageSource(imageSource, request); }
@Test public void calculateInSampleSizeKeepAspectRatioWithWidth() { final BitmapFactory.Options options = new BitmapFactory.Options(); Request data = new Request.Builder(URI_1).resize(400, 0).build(); calculateInSampleSize(data.targetWidth, data.targetHeight, 800, 200, options, data); assertThat(options.inSampleSize).isEqualTo(2); }
@Test public void inJustDecodeBoundsIfResizing() { // Resize must return bitmap options with inJustDecodeBounds = true final Request requiresResize = new Request.Builder(URI_1).resize(20, 15).build(); final BitmapFactory.Options resizeOptions = createBitmapOptions(requiresResize); assertThat(resizeOptions).isNotNull(); assertThat(resizeOptions.inJustDecodeBounds).isTrue(); assertThat(resizeOptions.inPurgeable).isFalse(); assertThat(resizeOptions.inInputShareable).isFalse(); }