Home | History | Annotate | Download | only in util
      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 
     21     private Util() {
     22         // Utility class.
     23     }
     24 
     25     /**
     26      * Returns the hex string of the given byte array representing a SHA256 hash.
     27      */
     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      */
     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
     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
     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)
     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      */
     84     public static int getBitmapByteSize(int width, int height, Bitmap.Config config) {
     85         return width * height * getBytesPerPixel(config);
     86     }
     87 
     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      */
    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      */
    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      */
    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      */
    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      */
    145     public static <T> Queue<T> createQueue(int size) {
    146         return new ArrayDeque<T>(size);
    147     }
    148 }
    149