aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/android/volley/toolbox/ImageRequest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/android/volley/toolbox/ImageRequest.java')
-rw-r--r--src/main/java/com/android/volley/toolbox/ImageRequest.java283
1 files changed, 0 insertions, 283 deletions
diff --git a/src/main/java/com/android/volley/toolbox/ImageRequest.java b/src/main/java/com/android/volley/toolbox/ImageRequest.java
deleted file mode 100644
index 32b5aa3..0000000
--- a/src/main/java/com/android/volley/toolbox/ImageRequest.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.volley.toolbox;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.BitmapFactory;
-import android.widget.ImageView.ScaleType;
-import androidx.annotation.GuardedBy;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import com.android.volley.DefaultRetryPolicy;
-import com.android.volley.NetworkResponse;
-import com.android.volley.ParseError;
-import com.android.volley.Request;
-import com.android.volley.Response;
-import com.android.volley.VolleyLog;
-
-/** A canned request for getting an image at a given URL and calling back with a decoded Bitmap. */
-public class ImageRequest extends Request<Bitmap> {
- /** Socket timeout in milliseconds for image requests */
- public static final int DEFAULT_IMAGE_TIMEOUT_MS = 1000;
-
- /** Default number of retries for image requests */
- public static final int DEFAULT_IMAGE_MAX_RETRIES = 2;
-
- /** Default backoff multiplier for image requests */
- public static final float DEFAULT_IMAGE_BACKOFF_MULT = 2f;
-
- /** Lock to guard mListener as it is cleared on cancel() and read on delivery. */
- private final Object mLock = new Object();
-
- @GuardedBy("mLock")
- @Nullable
- private Response.Listener<Bitmap> mListener;
-
- private final Config mDecodeConfig;
- private final int mMaxWidth;
- private final int mMaxHeight;
- private final ScaleType mScaleType;
-
- /** Decoding lock so that we don't decode more than one image at a time (to avoid OOM's) */
- private static final Object sDecodeLock = new Object();
-
- /**
- * Creates a new image request, decoding to a maximum specified width and height. If both width
- * and height are zero, the image will be decoded to its natural size. If one of the two is
- * nonzero, that dimension will be clamped and the other one will be set to preserve the image's
- * aspect ratio. If both width and height are nonzero, the image will be decoded to be fit in
- * the rectangle of dimensions width x height while keeping its aspect ratio.
- *
- * @param url URL of the image
- * @param listener Listener to receive the decoded bitmap
- * @param maxWidth Maximum width to decode this bitmap to, or zero for none
- * @param maxHeight Maximum height to decode this bitmap to, or zero for none
- * @param scaleType The ImageViews ScaleType used to calculate the needed image size.
- * @param decodeConfig Format to decode the bitmap to
- * @param errorListener Error listener, or null to ignore errors
- */
- public ImageRequest(
- String url,
- Response.Listener<Bitmap> listener,
- int maxWidth,
- int maxHeight,
- ScaleType scaleType,
- Config decodeConfig,
- @Nullable Response.ErrorListener errorListener) {
- super(Method.GET, url, errorListener);
- setRetryPolicy(
- new DefaultRetryPolicy(
- DEFAULT_IMAGE_TIMEOUT_MS,
- DEFAULT_IMAGE_MAX_RETRIES,
- DEFAULT_IMAGE_BACKOFF_MULT));
- mListener = listener;
- mDecodeConfig = decodeConfig;
- mMaxWidth = maxWidth;
- mMaxHeight = maxHeight;
- mScaleType = scaleType;
- }
-
- /**
- * For API compatibility with the pre-ScaleType variant of the constructor. Equivalent to the
- * normal constructor with {@code ScaleType.CENTER_INSIDE}.
- */
- @Deprecated
- public ImageRequest(
- String url,
- Response.Listener<Bitmap> listener,
- int maxWidth,
- int maxHeight,
- Config decodeConfig,
- Response.ErrorListener errorListener) {
- this(
- url,
- listener,
- maxWidth,
- maxHeight,
- ScaleType.CENTER_INSIDE,
- decodeConfig,
- errorListener);
- }
-
- @Override
- public Priority getPriority() {
- return Priority.LOW;
- }
-
- /**
- * Scales one side of a rectangle to fit aspect ratio.
- *
- * @param maxPrimary Maximum size of the primary dimension (i.e. width for max width), or zero
- * to maintain aspect ratio with secondary dimension
- * @param maxSecondary Maximum size of the secondary dimension, or zero to maintain aspect ratio
- * with primary dimension
- * @param actualPrimary Actual size of the primary dimension
- * @param actualSecondary Actual size of the secondary dimension
- * @param scaleType The ScaleType used to calculate the needed image size.
- */
- private static int getResizedDimension(
- int maxPrimary,
- int maxSecondary,
- int actualPrimary,
- int actualSecondary,
- ScaleType scaleType) {
-
- // If no dominant value at all, just return the actual.
- if ((maxPrimary == 0) && (maxSecondary == 0)) {
- return actualPrimary;
- }
-
- // If ScaleType.FIT_XY fill the whole rectangle, ignore ratio.
- if (scaleType == ScaleType.FIT_XY) {
- if (maxPrimary == 0) {
- return actualPrimary;
- }
- return maxPrimary;
- }
-
- // If primary is unspecified, scale primary to match secondary's scaling ratio.
- if (maxPrimary == 0) {
- double ratio = (double) maxSecondary / (double) actualSecondary;
- return (int) (actualPrimary * ratio);
- }
-
- if (maxSecondary == 0) {
- return maxPrimary;
- }
-
- double ratio = (double) actualSecondary / (double) actualPrimary;
- int resized = maxPrimary;
-
- // If ScaleType.CENTER_CROP fill the whole rectangle, preserve aspect ratio.
- if (scaleType == ScaleType.CENTER_CROP) {
- if ((resized * ratio) < maxSecondary) {
- resized = (int) (maxSecondary / ratio);
- }
- return resized;
- }
-
- if ((resized * ratio) > maxSecondary) {
- resized = (int) (maxSecondary / ratio);
- }
- return resized;
- }
-
- @Override
- protected Response<Bitmap> parseNetworkResponse(NetworkResponse response) {
- // Serialize all decode on a global lock to reduce concurrent heap usage.
- synchronized (sDecodeLock) {
- try {
- return doParse(response);
- } catch (OutOfMemoryError e) {
- VolleyLog.e("Caught OOM for %d byte image, url=%s", response.data.length, getUrl());
- return Response.error(new ParseError(e));
- }
- }
- }
-
- /** The real guts of parseNetworkResponse. Broken out for readability. */
- private Response<Bitmap> doParse(NetworkResponse response) {
- byte[] data = response.data;
- BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
- Bitmap bitmap = null;
- if (mMaxWidth == 0 && mMaxHeight == 0) {
- decodeOptions.inPreferredConfig = mDecodeConfig;
- bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
- } else {
- // If we have to resize this image, first get the natural bounds.
- decodeOptions.inJustDecodeBounds = true;
- BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
- int actualWidth = decodeOptions.outWidth;
- int actualHeight = decodeOptions.outHeight;
-
- // Then compute the dimensions we would ideally like to decode to.
- int desiredWidth =
- getResizedDimension(
- mMaxWidth, mMaxHeight, actualWidth, actualHeight, mScaleType);
- int desiredHeight =
- getResizedDimension(
- mMaxHeight, mMaxWidth, actualHeight, actualWidth, mScaleType);
-
- // Decode to the nearest power of two scaling factor.
- decodeOptions.inJustDecodeBounds = false;
- // TODO(ficus): Do we need this or is it okay since API 8 doesn't support it?
- // decodeOptions.inPreferQualityOverSpeed = PREFER_QUALITY_OVER_SPEED;
- decodeOptions.inSampleSize =
- findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
- Bitmap tempBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
-
- // If necessary, scale down to the maximal acceptable size.
- if (tempBitmap != null
- && (tempBitmap.getWidth() > desiredWidth
- || tempBitmap.getHeight() > desiredHeight)) {
- bitmap = Bitmap.createScaledBitmap(tempBitmap, desiredWidth, desiredHeight, true);
- tempBitmap.recycle();
- } else {
- bitmap = tempBitmap;
- }
- }
-
- if (bitmap == null) {
- return Response.error(new ParseError(response));
- } else {
- return Response.success(bitmap, HttpHeaderParser.parseCacheHeaders(response));
- }
- }
-
- @Override
- public void cancel() {
- super.cancel();
- synchronized (mLock) {
- mListener = null;
- }
- }
-
- @Override
- protected void deliverResponse(Bitmap response) {
- Response.Listener<Bitmap> listener;
- synchronized (mLock) {
- listener = mListener;
- }
- if (listener != null) {
- listener.onResponse(response);
- }
- }
-
- /**
- * Returns the largest power-of-two divisor for use in downscaling a bitmap that will not result
- * in the scaling past the desired dimensions.
- *
- * @param actualWidth Actual width of the bitmap
- * @param actualHeight Actual height of the bitmap
- * @param desiredWidth Desired width of the bitmap
- * @param desiredHeight Desired height of the bitmap
- */
- @VisibleForTesting
- static int findBestSampleSize(
- int actualWidth, int actualHeight, int desiredWidth, int desiredHeight) {
- double wr = (double) actualWidth / desiredWidth;
- double hr = (double) actualHeight / desiredHeight;
- double ratio = Math.min(wr, hr);
- float n = 1.0f;
- while ((n * 2) <= ratio) {
- n *= 2;
- }
-
- return (int) n;
- }
-}