1f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka/*
2f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * Copyright (C) 2010 The Android Open Source Project
3f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka *
4f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * Licensed under the Apache License, Version 2.0 (the "License");
5f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * you may not use this file except in compliance with the License.
6f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * You may obtain a copy of the License at
7f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka *
8f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka *      http://www.apache.org/licenses/LICENSE-2.0
9f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka *
10f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * Unless required by applicable law or agreed to in writing, software
11f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * distributed under the License is distributed on an "AS IS" BASIS,
12f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * See the License for the specific language governing permissions and
14f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * limitations under the License.
15f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka */
16f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
17f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkapackage com.android.gallery3d.common;
18f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
19f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.database.Cursor;
20f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyalimport android.graphics.RectF;
21f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.os.ParcelFileDescriptor;
22f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.util.Log;
23f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
24f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport java.io.Closeable;
25f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport java.io.IOException;
26f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
27f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkapublic class Utils {
28f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    private static final String TAG = "Utils";
29f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
30f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    // Throws AssertionError if the input is false.
31f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    public static void assertTrue(boolean cond) {
32f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        if (!cond) {
33f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka            throw new AssertionError();
34f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        }
35f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    }
36f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
37f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    // Returns the next power of two.
38f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    // Returns the input if it is already power of 2.
39f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    // Throws IllegalArgumentException if the input is <= 0 or
40f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    // the answer overflows.
41f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    public static int nextPowerOf2(int n) {
42f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        if (n <= 0 || n > (1 << 30)) throw new IllegalArgumentException("n is invalid: " + n);
43f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        n -= 1;
44f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        n |= n >> 16;
45f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        n |= n >> 8;
46f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        n |= n >> 4;
47f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        n |= n >> 2;
48f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        n |= n >> 1;
49f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        return n + 1;
50f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    }
51f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
52f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    // Returns the previous power of two.
53f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    // Returns the input if it is already power of 2.
54f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    // Throws IllegalArgumentException if the input is <= 0
55f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    public static int prevPowerOf2(int n) {
56f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        if (n <= 0) throw new IllegalArgumentException();
57f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        return Integer.highestOneBit(n);
58f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    }
59f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
60f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    // Returns the input value x clamped to the range [min, max].
61f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    public static int clamp(int x, int min, int max) {
62f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        if (x > max) return max;
63f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        if (x < min) return min;
64f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        return x;
65f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    }
66f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
67f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    public static int ceilLog2(float value) {
68f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        int i;
69f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        for (i = 0; i < 31; i++) {
70f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka            if ((1 << i) >= value) break;
71f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        }
72f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        return i;
73f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    }
74f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
75f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    public static int floorLog2(float value) {
76f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        int i;
77f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        for (i = 0; i < 31; i++) {
78f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka            if ((1 << i) > value) break;
79f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        }
80f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        return i - 1;
81f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    }
82f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
83f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal    public static void closeSilently(Closeable c) {
84f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        if (c == null) return;
85f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        try {
86f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal            c.close();
87f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        } catch (IOException t) {
88f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal            Log.w(TAG, "close fail ", t);
89f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        }
90f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal    }
91f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal
92f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    public static void closeSilently(ParcelFileDescriptor fd) {
93f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        try {
94f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka            if (fd != null) fd.close();
95f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        } catch (Throwable t) {
96f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka            Log.w(TAG, "fail to close", t);
97f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        }
98f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    }
99f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
100f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    public static void closeSilently(Cursor cursor) {
101f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        try {
102f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka            if (cursor != null) cursor.close();
103f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        } catch (Throwable t) {
104f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka            Log.w(TAG, "fail to close", t);
105f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka        }
106f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    }
107f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka
108f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal    public static RectF getMaxCropRect(
109f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal            int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) {
110f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        RectF cropRect = new RectF();
111f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        // Get a crop rect that will fit this
112f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        if (inWidth / (float) inHeight > outWidth / (float) outHeight) {
113f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal             cropRect.top = 0;
114f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal             cropRect.bottom = inHeight;
115f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal             cropRect.left = (inWidth - (outWidth / (float) outHeight) * inHeight) / 2;
116f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal             cropRect.right = inWidth - cropRect.left;
117f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal             if (leftAligned) {
118f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal                 cropRect.right -= cropRect.left;
119f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal                 cropRect.left = 0;
120f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal             }
121f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        } else {
122f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal            cropRect.left = 0;
123f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal            cropRect.right = inWidth;
124f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal            cropRect.top = (inHeight - (outHeight / (float) outWidth) * inWidth) / 2;
125f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal            cropRect.bottom = inHeight - cropRect.top;
126f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        }
127f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal        return cropRect;
128f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka    }
129841a502864d307341945eae62569b92cada93e75Sunny Goyal
130841a502864d307341945eae62569b92cada93e75Sunny Goyal    /**
131841a502864d307341945eae62569b92cada93e75Sunny Goyal     * Find the min x that 1 / x >= scale
132841a502864d307341945eae62569b92cada93e75Sunny Goyal     */
133841a502864d307341945eae62569b92cada93e75Sunny Goyal    public static int computeSampleSizeLarger(float scale) {
134841a502864d307341945eae62569b92cada93e75Sunny Goyal        int initialSize = (int) Math.floor(1f / scale);
135841a502864d307341945eae62569b92cada93e75Sunny Goyal        if (initialSize <= 1) return 1;
136841a502864d307341945eae62569b92cada93e75Sunny Goyal        return initialSize <= 8 ? prevPowerOf2(initialSize) : (initialSize / 8 * 8);
137841a502864d307341945eae62569b92cada93e75Sunny Goyal    }
138f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka}
139