1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.camera.util;
18 
19 import android.annotation.TargetApi;
20 import android.graphics.Point;
21 import android.graphics.Rect;
22 import android.hardware.Camera;
23 import android.os.Build.VERSION_CODES;
24 import android.text.TextUtils;
25 
26 import com.google.common.base.Objects;
27 
28 import java.util.ArrayList;
29 import java.util.List;
30 
31 /**
32  * Simple size class until we are 'L' only and can use android.util.Size.
33  */
34 public class Size {
35     public static final String LIST_DELIMITER = ",";
36 
37     private final int width;
38     private final int height;
39 
Size(Point point)40     public Size(Point point) {
41         this.width = point.x;
42         this.height = point.y;
43     }
44 
45     @TargetApi(VERSION_CODES.LOLLIPOP)
Size(android.util.Size size)46     public Size(android.util.Size size) {
47         this.width = size.getWidth();
48         this.height = size.getHeight();
49     }
50 
Size(int width, int height)51     public Size(int width, int height) {
52         this.width = width;
53         this.height = height;
54     }
55 
of(Rect rectangle)56     public static Size of(Rect rectangle) {
57         return new Size(rectangle.width(), rectangle.height());
58     }
59 
60     /**
61      * Constructor from a source {@link android.hardware.Camera.Size}.
62      *
63      * @param other The source size.
64      */
Size(Camera.Size other)65     public Size(Camera.Size other) {
66         this.width = other.width;
67         this.height = other.height;
68     }
69 
Size(com.android.ex.camera2.portability.Size size)70     public Size(com.android.ex.camera2.portability.Size size) {
71         this.width = size.width();
72         this.height = size.height();
73     }
74 
getWidth()75     public int getWidth() {
76         return width;
77     }
78 
getHeight()79     public int getHeight() {
80         return height;
81     }
82 
width()83     public int width() {
84         return width;
85     }
86 
height()87     public int height() {
88         return height;
89     }
90 
91     @Override
toString()92     public String toString() {
93         return width + "x" + height;
94     }
95 
transpose()96     public Size transpose() {
97         return new Size(height, width);
98     }
99 
100     /**
101      * @return The landscape version of this size.
102      */
asLandscape()103     public Size asLandscape() {
104         if (isLandscape()) {
105             return this;
106         } else {
107             return transpose();
108         }
109     }
110 
111     /**
112      * @return The portrait version of this size.
113      */
asPortrait()114     public Size asPortrait() {
115         if (isPortrait()) {
116             return this;
117         } else {
118             return transpose();
119         }
120     }
121 
area()122     public long area() {
123         return width * height;
124     }
125 
126     /** Returns width/height. */
aspectRatio()127     public float aspectRatio() {
128         return (float) width / height;
129     }
130 
131     @Override
equals(Object other)132     public boolean equals(Object other) {
133         if (!(other instanceof Size)) {
134             return false;
135         }
136 
137         Size otherSize = (Size) other;
138         return otherSize.width == this.width && otherSize.height == this.height;
139     }
140 
141     @Override
hashCode()142     public int hashCode() {
143         return Objects.hashCode(width, height);
144     }
145 
toPortabilitySize()146     public com.android.ex.camera2.portability.Size toPortabilitySize() {
147         return new com.android.ex.camera2.portability.Size(width, height);
148     }
149 
150     @TargetApi(VERSION_CODES.LOLLIPOP)
convert(android.util.Size[] sizes)151     public static Size[] convert(android.util.Size[] sizes) {
152         Size[] converted = new Size[sizes.length];
153         for (int i = 0; i < sizes.length; ++i) {
154             converted[i] = new Size(sizes[i].getWidth(), sizes[i].getHeight());
155         }
156         return converted;
157     }
158 
convert(List<com.android.ex.camera2.portability.Size> sizes)159     public static List<Size> convert(List<com.android.ex.camera2.portability.Size> sizes) {
160         ArrayList<Size> converted = new ArrayList<>(sizes.size());
161         for (com.android.ex.camera2.portability.Size size : sizes) {
162             converted.add(new Size(size.width(), size.height()));
163         }
164         return converted;
165     }
166 
167     /**
168      * Encode List of this class as comma-separated list of integers.
169      *
170      * @param sizes List of this class to encode.
171      * @return encoded string.
172      */
listToString(List<Size> sizes)173     public static String listToString(List<Size> sizes) {
174         ArrayList<Integer> flatSizes = new ArrayList<>();
175         for (Size s : sizes) {
176             flatSizes.add(s.width());
177             flatSizes.add(s.height());
178         }
179         return TextUtils.join(LIST_DELIMITER, flatSizes);
180     }
181 
182     /**
183      * Decode comma-separated even-length list of integers into a List of this class.
184      *
185      * @param encodedSizes encoded string.
186      * @return List of this class.
187      */
stringToList(String encodedSizes)188     public static List<Size> stringToList(String encodedSizes) {
189         String[] flatSizes = TextUtils.split(encodedSizes, LIST_DELIMITER);
190         ArrayList<Size> list = new ArrayList<>();
191         for (int i = 0; i < flatSizes.length; i += 2) {
192             int width = Integer.parseInt(flatSizes[i]);
193             int height = Integer.parseInt(flatSizes[i + 1]);
194             list.add(new Size(width, height));
195         }
196         return list;
197     }
198 
199     /**
200      * An helper method to build a list of this class from a list of
201      * {@link android.hardware.Camera.Size}.
202      *
203      * @param cameraSizes Source.
204      * @return The built list.
205      */
buildListFromCameraSizes(List<Camera.Size> cameraSizes)206     public static List<Size> buildListFromCameraSizes(List<Camera.Size> cameraSizes) {
207         ArrayList<Size> list = new ArrayList<Size>(cameraSizes.size());
208         for (Camera.Size cameraSize : cameraSizes) {
209             list.add(new Size(cameraSize));
210         }
211         return list;
212     }
213 
214     /**
215      * @return True if this size is in landscape orientation. Square
216      *         sizes are both portrait *and* landscape.
217      */
isLandscape()218     private boolean isLandscape() {
219         return width >= height;
220     }
221 
222     /**
223      * @return True if this size is in portrait orientation. Square
224      *         sizes are both portrait *and* landscape.
225      */
isPortrait()226     private boolean isPortrait() {
227         return height >= width;
228     }
229 }
230