• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.bumptech.glide.util;
2 
3 import android.annotation.TargetApi;
4 import android.graphics.Bitmap;
5 import android.os.Build;
6 import android.os.Looper;
7 
8 import java.util.ArrayDeque;
9 import java.util.Queue;
10 
11 /**
12  * A collection of assorted utility classes.
13  */
14 public final class Util {
15     private static final char[] HEX_CHAR_ARRAY = "0123456789abcdef".toCharArray();
16     // 32 bytes from sha-256 -> 64 hex chars.
17     private static final char[] SHA_256_CHARS = new char[64];
18     // 20 bytes from sha-1 -> 40 chars.
19     private static final char[] SHA_1_CHARS = new char[40];
20 
Util()21     private Util() {
22         // Utility class.
23     }
24 
25     /**
26      * Returns the hex string of the given byte array representing a SHA256 hash.
27      */
sha256BytesToHex(byte[] bytes)28     public static String sha256BytesToHex(byte[] bytes) {
29         return bytesToHex(bytes, SHA_256_CHARS);
30     }
31 
32     /**
33      * Returns the hex string of the given byte array representing a SHA1 hash.
34      */
sha1BytesToHex(byte[] bytes)35     public static String sha1BytesToHex(byte[] bytes) {
36         return bytesToHex(bytes, SHA_1_CHARS);
37     }
38 
39     // Taken from:
40     // http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java/9655275#9655275
bytesToHex(byte[] bytes, char[] hexChars)41     private static String bytesToHex(byte[] bytes, char[] hexChars) {
42         int v;
43         for (int j = 0; j < bytes.length; j++) {
44             v = bytes[j] & 0xFF;
45             hexChars[j * 2] = HEX_CHAR_ARRAY[v >>> 4];
46             hexChars[j * 2 + 1] = HEX_CHAR_ARRAY[v & 0x0F];
47         }
48         return new String(hexChars);
49     }
50 
51     /**
52      * Returns the allocated byte size of the given bitmap.
53      *
54      * @see #getBitmapByteSize(android.graphics.Bitmap)
55      *
56      * @deprecated Use {@link #getBitmapByteSize(android.graphics.Bitmap)} instead. Scheduled to be removed in Glide
57      * 4.0.
58      */
59     @Deprecated
getSize(Bitmap bitmap)60     public static int getSize(Bitmap bitmap) {
61         return getBitmapByteSize(bitmap);
62     }
63 
64     /**
65      * Returns the in memory size of the given {@link Bitmap} in bytes.
66      */
67     @TargetApi(Build.VERSION_CODES.KITKAT)
getBitmapByteSize(Bitmap bitmap)68     public static int getBitmapByteSize(Bitmap bitmap) {
69         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
70             // Workaround for KitKat initial release NPE in Bitmap, fixed in MR1. See issue #148.
71             try {
72                 return bitmap.getAllocationByteCount();
73             } catch (NullPointerException e) {
74                 // Do nothing.
75             }
76         }
77         return bitmap.getHeight() * bitmap.getRowBytes();
78     }
79 
80     /**
81      * Returns the in memory size of {@link android.graphics.Bitmap} with the given width, height, and
82      * {@link android.graphics.Bitmap.Config}.
83      */
getBitmapByteSize(int width, int height, Bitmap.Config config)84     public static int getBitmapByteSize(int width, int height, Bitmap.Config config) {
85         return width * height * getBytesPerPixel(config);
86     }
87 
getBytesPerPixel(Bitmap.Config config)88     private static int getBytesPerPixel(Bitmap.Config config) {
89         // A bitmap by decoding a gif has null "config" in certain environments.
90         if (config == null) {
91             config = Bitmap.Config.ARGB_8888;
92         }
93 
94         int bytesPerPixel;
95         switch (config) {
96             case ALPHA_8:
97                 bytesPerPixel = 1;
98                 break;
99             case RGB_565:
100             case ARGB_4444:
101                 bytesPerPixel = 2;
102                 break;
103             case ARGB_8888:
104             default:
105                 bytesPerPixel = 4;
106         }
107         return bytesPerPixel;
108     }
109 
110     /**
111      * Throws an {@link java.lang.IllegalArgumentException} if called on a thread other than the main thread.
112      */
assertMainThread()113     public static void assertMainThread() {
114         if (!isOnMainThread()) {
115             throw new IllegalArgumentException("You must call this method on the main thread");
116         }
117     }
118 
119     /**
120      * Throws an {@link java.lang.IllegalArgumentException} if called on the main thread.
121      */
assertBackgroundThread()122     public static void assertBackgroundThread() {
123         if (!isOnBackgroundThread()) {
124             throw new IllegalArgumentException("YOu must call this method on a background thread");
125         }
126     }
127 
128     /**
129      * Returns {@code true} if called on the main thread, {@code false} otherwise.
130      */
isOnMainThread()131     public static boolean isOnMainThread() {
132         return Looper.myLooper() == Looper.getMainLooper();
133     }
134 
135     /**
136      * Returns {@code true} if called on the main thread, {@code false} otherwise.
137      */
isOnBackgroundThread()138     public static boolean isOnBackgroundThread() {
139         return !isOnMainThread();
140     }
141 
142     /**
143      * Creates a {@link java.util.Queue} of the given size using Glide's preferred implementation.
144      */
createQueue(int size)145     public static <T> Queue<T> createQueue(int size) {
146         return new ArrayDeque<T>(size);
147     }
148 }
149