OSDN Git Service

merge in jb-mr2-release history after reset to master
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / presets / ImagePreset.java
1 /*
2  * Copyright (C) 2012 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.gallery3d.filtershow.presets;
18
19 import android.graphics.Bitmap;
20 import android.graphics.Rect;
21 import android.util.Log;
22
23 import com.android.gallery3d.filtershow.ImageStateAdapter;
24 import com.android.gallery3d.filtershow.cache.ImageLoader;
25 import com.android.gallery3d.filtershow.filters.BaseFiltersManager;
26 import com.android.gallery3d.filtershow.filters.FilterRepresentation;
27 import com.android.gallery3d.filtershow.filters.FiltersManager;
28 import com.android.gallery3d.filtershow.filters.ImageFilter;
29 import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
30 import com.android.gallery3d.filtershow.imageshow.MasterImage;
31
32 import java.util.Vector;
33
34 public class ImagePreset {
35
36     private static final String LOGTAG = "ImagePreset";
37
38     private FilterRepresentation mBorder = null;
39     private float mScaleFactor = 1.0f;
40     public static final int QUALITY_ICON = 0;
41     public static final int QUALITY_PREVIEW = 1;
42     public static final int QUALITY_FINAL = 2;
43     private int mQuality = QUALITY_PREVIEW;
44     private ImageLoader mImageLoader = null;
45
46     private Vector<FilterRepresentation> mFilters = new Vector<FilterRepresentation>();
47
48     protected String mName = "Original";
49     private String mHistoryName = "Original";
50     protected boolean mIsFxPreset = false;
51
52     private boolean mDoApplyGeometry = true;
53     private boolean mDoApplyFilters = true;
54
55     public final GeometryMetadata mGeoData = new GeometryMetadata();
56     private boolean mPartialRendering = false;
57     private Rect mPartialRenderingBounds;
58
59     public ImagePreset() {
60         setup();
61     }
62
63     public ImagePreset(String historyName) {
64         setHistoryName(historyName);
65         setup();
66     }
67
68     public ImagePreset(ImagePreset source, String historyName) {
69         this(source);
70         if (historyName != null) {
71             setHistoryName(historyName);
72         }
73     }
74
75     public ImagePreset(ImagePreset source) {
76         try {
77             if (source.mBorder != null) {
78                 mBorder = source.mBorder.clone();
79             }
80             for (int i = 0; i < source.mFilters.size(); i++) {
81                 FilterRepresentation representation = source.mFilters.elementAt(i).clone();
82                 addFilter(representation);
83             }
84         } catch (java.lang.CloneNotSupportedException e) {
85             Log.v(LOGTAG, "Exception trying to clone: " + e);
86         }
87         mName = source.name();
88         mHistoryName = source.name();
89         mIsFxPreset = source.isFx();
90         mImageLoader = source.getImageLoader();
91
92         mGeoData.set(source.mGeoData);
93     }
94
95     public FilterRepresentation getFilterRepresentation(int position) {
96         FilterRepresentation representation = null;
97         try {
98             representation = mFilters.elementAt(position).clone();
99         } catch (CloneNotSupportedException e) {
100             e.printStackTrace();
101         }
102         return representation;
103     }
104
105     public int getPositionForRepresentation(FilterRepresentation representation) {
106         for (int i = 0; i < mFilters.size(); i++) {
107             if (mFilters.elementAt(i).getFilterClass() == representation.getFilterClass()) {
108                 return i;
109             }
110         }
111         return -1;
112     }
113
114     public FilterRepresentation getFilterRepresentationCopyFrom(FilterRepresentation filterRepresentation) {
115         // TODO: add concept of position in the filters (to allow multiple instances)
116         if (filterRepresentation == null) {
117             return null;
118         }
119         int position = getPositionForRepresentation(filterRepresentation);
120         if (position == -1) {
121             return null;
122         }
123         FilterRepresentation representation = null;
124         try {
125             representation = mFilters.elementAt(position).clone();
126         } catch (CloneNotSupportedException e) {
127             e.printStackTrace();
128         }
129         return representation;
130     }
131
132     public void updateFilterRepresentation(FilterRepresentation representation) {
133         synchronized (mFilters) {
134             int position = getPositionForRepresentation(representation);
135             FilterRepresentation old = mFilters.elementAt(position);
136             old.updateTempParametersFrom(representation);
137         }
138         MasterImage.getImage().invalidatePreview();
139     }
140
141     public void setDoApplyGeometry(boolean value) {
142         mDoApplyGeometry = value;
143     }
144
145     public void setDoApplyFilters(boolean value) {
146         mDoApplyFilters = value;
147     }
148
149     public boolean getDoApplyFilters() {
150         return mDoApplyFilters;
151     }
152
153     public synchronized GeometryMetadata getGeometry() {
154         return mGeoData;
155     }
156
157     public boolean hasModifications() {
158         if (mBorder != null && !mBorder.isNil()) {
159             return true;
160         }
161         if (mGeoData.hasModifications()) {
162             return true;
163         }
164         for (int i = 0; i < mFilters.size(); i++) {
165             FilterRepresentation filter = mFilters.elementAt(i);
166             if (!filter.isNil()) {
167                 return true;
168             }
169         }
170         return false;
171     }
172
173     public boolean isPanoramaSafe() {
174         if (mBorder != null && !mBorder.isNil()) {
175             return false;
176         }
177         if (mGeoData.hasModifications()) {
178             return false;
179         }
180         for (FilterRepresentation representation : mFilters) {
181             if (representation.getPriority() == FilterRepresentation.TYPE_VIGNETTE
182                 && !representation.isNil()) {
183                 return false;
184             }
185             if (representation.getPriority() == FilterRepresentation.TYPE_TINYPLANET
186                 && !representation.isNil()) {
187                 return false;
188             }
189         }
190         return true;
191     }
192
193     public synchronized void setGeometry(GeometryMetadata m) {
194         mGeoData.set(m);
195     }
196
197     private void setBorder(FilterRepresentation filter) {
198         mBorder = filter;
199     }
200
201     public boolean isFx() {
202         return mIsFxPreset;
203     }
204
205     public void setIsFx(boolean value) {
206         mIsFxPreset = value;
207     }
208
209     public void setName(String name) {
210         mName = name;
211         mHistoryName = name;
212     }
213
214     public void setHistoryName(String name) {
215         mHistoryName = name;
216     }
217
218     public ImageLoader getImageLoader() {
219         return mImageLoader;
220     }
221
222     public void setImageLoader(ImageLoader mImageLoader) {
223         this.mImageLoader = mImageLoader;
224     }
225
226     public boolean equals(ImagePreset preset) {
227         if (!same(preset)) {
228             return false;
229         }
230         if (mDoApplyFilters && preset.mDoApplyFilters) {
231             for (int i = 0; i < preset.mFilters.size(); i++) {
232                 FilterRepresentation a = preset.mFilters.elementAt(i);
233                 FilterRepresentation b = mFilters.elementAt(i);
234                 if (!a.equals(b)) {
235                     return false;
236                 }
237             }
238         }
239         return true;
240     }
241
242     public boolean same(ImagePreset preset) {
243         if (preset == null) {
244             return false;
245         }
246
247         if (preset.mFilters.size() != mFilters.size()) {
248             return false;
249         }
250
251         if (!mName.equalsIgnoreCase(preset.name())) {
252             return false;
253         }
254
255         if (mDoApplyGeometry != preset.mDoApplyGeometry) {
256             return false;
257         }
258
259         if (mDoApplyGeometry && !mGeoData.equals(preset.mGeoData)) {
260             return false;
261         }
262
263         if (mDoApplyGeometry && mBorder != preset.mBorder) {
264             return false;
265         }
266
267         if (mBorder != null && !mBorder.equals(preset.mBorder)) {
268             return false;
269         }
270
271         if (mDoApplyFilters != preset.mDoApplyFilters) {
272             if (mFilters.size() > 0 || preset.mFilters.size() > 0) {
273                 return false;
274             }
275         }
276
277         if (mDoApplyFilters && preset.mDoApplyFilters) {
278             for (int i = 0; i < preset.mFilters.size(); i++) {
279                 FilterRepresentation a = preset.mFilters.elementAt(i);
280                 FilterRepresentation b = mFilters.elementAt(i);
281                 if (!a.same(b)) {
282                     return false;
283                 }
284             }
285         }
286
287         return true;
288     }
289
290     public int similarUpTo(ImagePreset preset) {
291         if (!mGeoData.equals(preset.mGeoData)) {
292             return -1;
293         }
294
295         for (int i = 0; i < preset.mFilters.size(); i++) {
296             FilterRepresentation a = preset.mFilters.elementAt(i);
297             if (i < mFilters.size()) {
298                 FilterRepresentation b = mFilters.elementAt(i);
299                 if (!a.same(b)) {
300                     return i;
301                 }
302                 if (!a.equals(b)) {
303                     return i;
304                 }
305             } else {
306                 return i;
307             }
308         }
309         return preset.mFilters.size();
310     }
311
312     public String name() {
313         return mName;
314     }
315
316     public String historyName() {
317         return mHistoryName;
318     }
319
320     public void showFilters() {
321         Log.v(LOGTAG, "\\\\\\ showFilters -- " + mFilters.size() + " filters");
322         int n = 0;
323         for (FilterRepresentation representation : mFilters) {
324             Log.v(LOGTAG, " filter " + n + " : " + representation.toString());
325             n++;
326         }
327         Log.v(LOGTAG, "/// showFilters -- " + mFilters.size() + " filters");
328     }
329
330     public void addFilter(FilterRepresentation representation) {
331         Log.v(LOGTAG, "*** Add Filter *** " + representation);
332         if (representation.getPriority() == FilterRepresentation.TYPE_BORDER) {
333             setHistoryName(representation.getName());
334             setBorder(representation);
335         } else if (representation.getPriority() == FilterRepresentation.TYPE_FX) {
336             boolean found = false;
337             for (int i = 0; i < mFilters.size(); i++) {
338                 int type = mFilters.elementAt(i).getPriority();
339                 if (found) {
340                     if (type != FilterRepresentation.TYPE_VIGNETTE) {
341                         mFilters.remove(i);
342                         continue;
343                     }
344                 }
345                 if (type == FilterRepresentation.TYPE_FX) {
346                     mFilters.remove(i);
347                     mFilters.add(i, representation);
348                     setHistoryName(representation.getName());
349                     found = true;
350                 }
351             }
352             if (!found) {
353                 mFilters.add(representation);
354                 setHistoryName(representation.getName());
355             }
356         } else {
357             mFilters.add(representation);
358             setHistoryName(representation.getName());
359         }
360     }
361
362     public FilterRepresentation getRepresentation(FilterRepresentation filterRepresentation) {
363         for (int i = 0; i < mFilters.size(); i++) {
364             FilterRepresentation representation = mFilters.elementAt(i);
365             if (representation.getFilterClass() == filterRepresentation.getFilterClass()) {
366                 return representation;
367             }
368         }
369         if (mBorder != null && mBorder.getFilterClass() == filterRepresentation.getFilterClass()) {
370             return mBorder;
371         }
372         return null;
373     }
374
375     public void setup() {
376         // do nothing here
377     }
378
379     public Bitmap apply(Bitmap original) {
380         Bitmap bitmap = original;
381         bitmap = applyFilters(bitmap, -1, -1);
382         return applyBorder(bitmap);
383     }
384
385     public Bitmap applyGeometry(Bitmap bitmap) {
386         // Apply any transform -- 90 rotate, flip, straighten, crop
387         // Returns a new bitmap.
388         return mGeoData.apply(bitmap, mScaleFactor, mQuality);
389     }
390
391     public Bitmap applyBorder(Bitmap bitmap) {
392         if (mBorder != null && mDoApplyGeometry) {
393             ImageFilter filter = FiltersManager.getManager().getFilterForRepresentation(mBorder);
394             mBorder.synchronizeRepresentation();
395             filter.useRepresentation(mBorder);
396             filter.setImagePreset(this);
397             bitmap = filter.apply(bitmap, mScaleFactor, mQuality);
398         }
399         return bitmap;
400     }
401
402     public Bitmap applyFilters(Bitmap bitmap, int from, int to) {
403
404         if (mDoApplyFilters) {
405             if (from < 0) {
406                 from = 0;
407             }
408             if (to == -1) {
409                 to = mFilters.size();
410             }
411             for (int i = from; i < to; i++) {
412                 FilterRepresentation representation = null;
413                 synchronized (mFilters) {
414                     representation = mFilters.elementAt(i);
415                     representation.synchronizeRepresentation();
416                 }
417                 ImageFilter filter = FiltersManager.getManager().getFilterForRepresentation(representation);
418                 filter.useRepresentation(representation);
419                 filter.setImagePreset(this);
420                 bitmap = filter.apply(bitmap, mScaleFactor, mQuality);
421             }
422         }
423
424         return bitmap;
425     }
426
427     public boolean canDoPartialRendering() {
428         if (mGeoData.hasModifications()) {
429             return false;
430         }
431         for (int i = 0; i < mFilters.size(); i++) {
432             FilterRepresentation representation = null;
433             synchronized (mFilters) {
434                 representation = mFilters.elementAt(i);
435             }
436             if (!representation.supportsPartialRendering()) {
437                 return false;
438             }
439         }
440         return true;
441     }
442
443     public void fillImageStateAdapter(ImageStateAdapter imageStateAdapter) {
444         if (imageStateAdapter == null) {
445             return;
446         }
447         imageStateAdapter.clear();
448         // TODO: re-enable the state panel
449         imageStateAdapter.addAll(mFilters);
450         imageStateAdapter.notifyDataSetChanged();
451     }
452
453     public float getScaleFactor() {
454         return mScaleFactor;
455     }
456
457     public int getQuality() {
458         return mQuality;
459     }
460
461     public void setQuality(int value) {
462         mQuality = value;
463     }
464
465     public void setScaleFactor(float value) {
466         mScaleFactor = value;
467     }
468
469     public void setPartialRendering(boolean partialRendering, Rect bounds) {
470         mPartialRendering = partialRendering;
471         mPartialRenderingBounds = bounds;
472     }
473
474     public boolean isPartialRendering() {
475         return mPartialRendering;
476     }
477
478     public Rect getPartialRenderingBounds() {
479         return mPartialRenderingBounds;
480     }
481 }