| /* |
| * Copyright (C) 2010 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.gallery3d.common; |
| |
| import android.database.Cursor; |
| import android.graphics.RectF; |
| import android.os.ParcelFileDescriptor; |
| import android.util.Log; |
| |
| import java.io.Closeable; |
| import java.io.IOException; |
| |
| public class Utils { |
| private static final String TAG = "Utils"; |
| |
| // Throws AssertionError if the input is false. |
| public static void assertTrue(boolean cond) { |
| if (!cond) { |
| throw new AssertionError(); |
| } |
| } |
| |
| // Returns the next power of two. |
| // Returns the input if it is already power of 2. |
| // Throws IllegalArgumentException if the input is <= 0 or |
| // the answer overflows. |
| public static int nextPowerOf2(int n) { |
| if (n <= 0 || n > (1 << 30)) throw new IllegalArgumentException("n is invalid: " + n); |
| n -= 1; |
| n |= n >> 16; |
| n |= n >> 8; |
| n |= n >> 4; |
| n |= n >> 2; |
| n |= n >> 1; |
| return n + 1; |
| } |
| |
| // Returns the previous power of two. |
| // Returns the input if it is already power of 2. |
| // Throws IllegalArgumentException if the input is <= 0 |
| public static int prevPowerOf2(int n) { |
| if (n <= 0) throw new IllegalArgumentException(); |
| return Integer.highestOneBit(n); |
| } |
| |
| // Returns the input value x clamped to the range [min, max]. |
| public static int clamp(int x, int min, int max) { |
| if (x > max) return max; |
| if (x < min) return min; |
| return x; |
| } |
| |
| public static int ceilLog2(float value) { |
| int i; |
| for (i = 0; i < 31; i++) { |
| if ((1 << i) >= value) break; |
| } |
| return i; |
| } |
| |
| public static int floorLog2(float value) { |
| int i; |
| for (i = 0; i < 31; i++) { |
| if ((1 << i) > value) break; |
| } |
| return i - 1; |
| } |
| |
| public static void closeSilently(Closeable c) { |
| if (c == null) return; |
| try { |
| c.close(); |
| } catch (IOException t) { |
| Log.w(TAG, "close fail ", t); |
| } |
| } |
| |
| public static void closeSilently(ParcelFileDescriptor fd) { |
| try { |
| if (fd != null) fd.close(); |
| } catch (Throwable t) { |
| Log.w(TAG, "fail to close", t); |
| } |
| } |
| |
| public static void closeSilently(Cursor cursor) { |
| try { |
| if (cursor != null) cursor.close(); |
| } catch (Throwable t) { |
| Log.w(TAG, "fail to close", t); |
| } |
| } |
| |
| public static RectF getMaxCropRect( |
| int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) { |
| RectF cropRect = new RectF(); |
| // Get a crop rect that will fit this |
| if (inWidth / (float) inHeight > outWidth / (float) outHeight) { |
| cropRect.top = 0; |
| cropRect.bottom = inHeight; |
| cropRect.left = (inWidth - (outWidth / (float) outHeight) * inHeight) / 2; |
| cropRect.right = inWidth - cropRect.left; |
| if (leftAligned) { |
| cropRect.right -= cropRect.left; |
| cropRect.left = 0; |
| } |
| } else { |
| cropRect.left = 0; |
| cropRect.right = inWidth; |
| cropRect.top = (inHeight - (outHeight / (float) outWidth) * inWidth) / 2; |
| cropRect.bottom = inHeight - cropRect.top; |
| } |
| return cropRect; |
| } |
| |
| /** |
| * Find the min x that 1 / x >= scale |
| */ |
| public static int computeSampleSizeLarger(float scale) { |
| int initialSize = (int) Math.floor(1f / scale); |
| if (initialSize <= 1) return 1; |
| return initialSize <= 8 ? prevPowerOf2(initialSize) : (initialSize / 8 * 8); |
| } |
| } |