• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
18 
19 import android.util.Log;
20 
21 import java.util.Objects;
22 
23 /**
24  * Describes a single native or variant format available for an image, coming from a
25  * BipImageProperties object.
26  *
27  * <p>This is not an object by specification, per say. It abstracts all the various native and
28  * variant formats available in a given set of image properties.
29  *
30  * <p>This BipImageFormat can be used to choose a specific BipImageDescriptor when downloading an
31  * image
32  *
33  * <p>Examples: <native encoding="JPEG" pixel="1280*1024” size="1048576"/> <variant encoding="JPEG"
34  * pixel="640*480"/> <variant encoding="JPEG" pixel="160*120"/> <variant encoding="GIF"
35  * pixel="80*60-640*480"/>
36  */
37 public class BipImageFormat {
38     private static final String TAG = "avrcpcontroller.BipImageFormat";
39 
40     public static final int FORMAT_NATIVE = 0;
41     public static final int FORMAT_VARIANT = 1;
42 
43     /** Create a native BipImageFormat from the given string fields */
parseNative(String encoding, String pixel, String size)44     public static BipImageFormat parseNative(String encoding, String pixel, String size) {
45         return new BipImageFormat(BipImageFormat.FORMAT_NATIVE, encoding, pixel, size, null, null);
46     }
47 
48     /** Create a variant BipImageFormat from the given string fields */
parseVariant( String encoding, String pixel, String maxSize, String transformation)49     public static BipImageFormat parseVariant(
50             String encoding, String pixel, String maxSize, String transformation) {
51         return new BipImageFormat(
52                 BipImageFormat.FORMAT_VARIANT, encoding, pixel, null, maxSize, transformation);
53     }
54 
55     /** Create a native BipImageFormat from the given parameters */
createNative(BipEncoding encoding, BipPixel pixel, int size)56     public static BipImageFormat createNative(BipEncoding encoding, BipPixel pixel, int size) {
57         return new BipImageFormat(BipImageFormat.FORMAT_NATIVE, encoding, pixel, size, -1, null);
58     }
59 
60     /** Create a variant BipImageFormat from the given parameters */
createVariant( BipEncoding encoding, BipPixel pixel, int maxSize, BipTransformation transformation)61     public static BipImageFormat createVariant(
62             BipEncoding encoding, BipPixel pixel, int maxSize, BipTransformation transformation) {
63         return new BipImageFormat(
64                 BipImageFormat.FORMAT_VARIANT, encoding, pixel, -1, maxSize, transformation);
65     }
66 
67     /** The 'flavor' of this image format, from the format constants above. */
68     private final int mFormatType;
69 
70     /** The encoding method in which this image is available, required by the specification */
71     private final BipEncoding mEncoding;
72 
73     /**
74      * The pixel size or range of pixel sizes in which the image is available, required by the
75      * specification
76      */
77     private final BipPixel mPixel;
78 
79     /**
80      * The list of supported image transformation methods, any of: - 'stretch' : Image server is
81      * capable of stretching the image to fit a space - 'fill' : Image server is capable of filling
82      * the image padding data to fit a space - 'crop' : Image server is capable of cropping the
83      * image down to fit a space
84      *
85      * <p>Used by the variant type only
86      */
87     private final BipTransformation mTransformation;
88 
89     /**
90      * Size in bytes of the image.
91      *
92      * <p>Used by the native type only
93      */
94     private final int mSize;
95 
96     /**
97      * The estimated maximum size of an image after a transformation is performed.
98      *
99      * <p>Used by the variant type only
100      */
101     private final int mMaxSize;
102 
BipImageFormat( int type, BipEncoding encoding, BipPixel pixel, int size, int maxSize, BipTransformation transformation)103     private BipImageFormat(
104             int type,
105             BipEncoding encoding,
106             BipPixel pixel,
107             int size,
108             int maxSize,
109             BipTransformation transformation) {
110         mFormatType = type;
111         mEncoding = Objects.requireNonNull(encoding, "Encoding cannot be null");
112         mPixel = Objects.requireNonNull(pixel, "Pixel cannot be null");
113         mTransformation = transformation;
114         mSize = size;
115         mMaxSize = maxSize;
116     }
117 
BipImageFormat( int type, String encoding, String pixel, String size, String maxSize, String transformation)118     private BipImageFormat(
119             int type,
120             String encoding,
121             String pixel,
122             String size,
123             String maxSize,
124             String transformation) {
125         mFormatType = type;
126         mEncoding = new BipEncoding(encoding);
127         mPixel = new BipPixel(pixel);
128         mTransformation = new BipTransformation(transformation);
129         mSize = parseInt(size);
130         mMaxSize = parseInt(maxSize);
131     }
132 
parseInt(String s)133     private static int parseInt(String s) {
134         if (s == null) return -1;
135         try {
136             return Integer.parseInt(s);
137         } catch (NumberFormatException e) {
138             error("Failed to parse '" + s + "'");
139         }
140         return -1;
141     }
142 
getType()143     public int getType() {
144         return mFormatType;
145     }
146 
getEncoding()147     public BipEncoding getEncoding() {
148         return mEncoding;
149     }
150 
getPixel()151     public BipPixel getPixel() {
152         return mPixel;
153     }
154 
getTransformation()155     public BipTransformation getTransformation() {
156         return mTransformation;
157     }
158 
getSize()159     public int getSize() {
160         return mSize;
161     }
162 
getMaxSize()163     public int getMaxSize() {
164         return mMaxSize;
165     }
166 
167     @Override
equals(Object o)168     public boolean equals(Object o) {
169         if (o == this) return true;
170         if (!(o instanceof BipImageFormat)) return false;
171 
172         BipImageFormat f = (BipImageFormat) o;
173         return f.getType() == getType()
174                 && f.getEncoding() == getEncoding()
175                 && f.getPixel() == getPixel()
176                 && f.getTransformation() == getTransformation()
177                 && f.getSize() == getSize()
178                 && f.getMaxSize() == getMaxSize();
179     }
180 
181     @Override
toString()182     public String toString() {
183         if (mEncoding == null
184                 || mEncoding.getType() == BipEncoding.UNKNOWN
185                 || mPixel == null
186                 || mPixel.getType() == BipPixel.TYPE_UNKNOWN) {
187             error(
188                     "Missing required fields [ "
189                             + (mEncoding == null ? "encoding " : "")
190                             + (mPixel == null ? "pixel " : ""));
191             return null;
192         }
193 
194         StringBuilder sb = new StringBuilder();
195         switch (mFormatType) {
196             case FORMAT_NATIVE:
197                 sb.append("<native");
198                 sb.append(" encoding=\"" + mEncoding.toString() + "\"");
199                 sb.append(" pixel=\"" + mPixel.toString() + "\"");
200                 if (mSize > -1) {
201                     sb.append(" size=\"" + mSize + "\"");
202                 }
203                 sb.append(" />");
204                 return sb.toString();
205             case FORMAT_VARIANT:
206                 sb.append("<variant");
207                 sb.append(" encoding=\"" + mEncoding.toString() + "\"");
208                 sb.append(" pixel=\"" + mPixel.toString() + "\"");
209                 if (mTransformation != null && mTransformation.supportsAny()) {
210                     sb.append(" transformation=\"" + mTransformation.toString() + "\"");
211                 }
212                 if (mSize > -1) {
213                     sb.append(" size=\"" + mSize + "\"");
214                 }
215                 if (mMaxSize > -1) {
216                     sb.append(" maxsize=\"" + mMaxSize + "\"");
217                 }
218                 sb.append(" />");
219                 return sb.toString();
220             default:
221                 error("Unsupported format type '" + mFormatType + "'");
222         }
223         return null;
224     }
225 
error(String msg)226     private static void error(String msg) {
227         Log.e(TAG, msg);
228     }
229 }
230