OSDN Git Service

merge in klp-release history after reset to klp-dev
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / pipeline / 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.pipeline;
18
19 import android.graphics.Bitmap;
20 import android.graphics.Rect;
21 import android.support.v8.renderscript.Allocation;
22 import android.util.JsonReader;
23 import android.util.JsonWriter;
24 import android.util.Log;
25
26 import com.android.gallery3d.R;
27 import com.android.gallery3d.filtershow.cache.BitmapCache;
28 import com.android.gallery3d.filtershow.cache.ImageLoader;
29 import com.android.gallery3d.filtershow.filters.BaseFiltersManager;
30 import com.android.gallery3d.filtershow.filters.FilterCropRepresentation;
31 import com.android.gallery3d.filtershow.filters.FilterFxRepresentation;
32 import com.android.gallery3d.filtershow.filters.FilterImageBorderRepresentation;
33 import com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation;
34 import com.android.gallery3d.filtershow.filters.FilterRepresentation;
35 import com.android.gallery3d.filtershow.filters.FilterRotateRepresentation;
36 import com.android.gallery3d.filtershow.filters.FilterStraightenRepresentation;
37 import com.android.gallery3d.filtershow.filters.FilterUserPresetRepresentation;
38 import com.android.gallery3d.filtershow.filters.FiltersManager;
39 import com.android.gallery3d.filtershow.filters.ImageFilter;
40 import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils;
41 import com.android.gallery3d.filtershow.imageshow.MasterImage;
42 import com.android.gallery3d.filtershow.state.State;
43 import com.android.gallery3d.filtershow.state.StateAdapter;
44 import com.android.gallery3d.util.UsageStatistics;
45
46 import java.io.IOException;
47 import java.io.StringReader;
48 import java.io.StringWriter;
49 import java.util.ArrayList;
50 import java.util.Collection;
51 import java.util.Vector;
52
53 public class ImagePreset {
54
55     private static final String LOGTAG = "ImagePreset";
56
57     private Vector<FilterRepresentation> mFilters = new Vector<FilterRepresentation>();
58
59     private boolean mDoApplyGeometry = true;
60     private boolean mDoApplyFilters = true;
61
62     private boolean mPartialRendering = false;
63     private Rect mPartialRenderingBounds;
64     private static final boolean DEBUG = false;
65
66     public ImagePreset() {
67     }
68
69     public ImagePreset(ImagePreset source) {
70         for (int i = 0; i < source.mFilters.size(); i++) {
71             FilterRepresentation sourceRepresentation = source.mFilters.elementAt(i);
72             mFilters.add(sourceRepresentation.copy());
73         }
74     }
75
76     public Vector<FilterRepresentation> getFilters() {
77         return mFilters;
78     }
79
80     public FilterRepresentation getFilterRepresentation(int position) {
81         FilterRepresentation representation = null;
82
83         representation = mFilters.elementAt(position).copy();
84
85         return representation;
86     }
87
88     private static boolean sameSerializationName(String a, String b) {
89         if (a != null && b != null) {
90             return a.equals(b);
91         } else {
92             return a == null && b == null;
93         }
94     }
95
96     public static boolean sameSerializationName(FilterRepresentation a, FilterRepresentation b) {
97         if (a == null || b == null) {
98             return false;
99         }
100         return sameSerializationName(a.getSerializationName(), b.getSerializationName());
101     }
102
103     public int getPositionForRepresentation(FilterRepresentation representation) {
104         for (int i = 0; i < mFilters.size(); i++) {
105             if (sameSerializationName(mFilters.elementAt(i), representation)) {
106                 return i;
107             }
108         }
109         return -1;
110     }
111
112     private FilterRepresentation getFilterRepresentationForType(int type) {
113         for (int i = 0; i < mFilters.size(); i++) {
114             if (mFilters.elementAt(i).getFilterType() == type) {
115                 return mFilters.elementAt(i);
116             }
117         }
118         return null;
119     }
120
121     public int getPositionForType(int type) {
122         for (int i = 0; i < mFilters.size(); i++) {
123             if (mFilters.elementAt(i).getFilterType() == type) {
124                 return i;
125             }
126         }
127         return -1;
128     }
129
130     public FilterRepresentation getFilterRepresentationCopyFrom(
131             FilterRepresentation filterRepresentation) {
132         // TODO: add concept of position in the filters (to allow multiple instances)
133         if (filterRepresentation == null) {
134             return null;
135         }
136         int position = getPositionForRepresentation(filterRepresentation);
137         if (position == -1) {
138             return null;
139         }
140         FilterRepresentation representation = mFilters.elementAt(position);
141         if (representation != null) {
142             representation = representation.copy();
143         }
144         return representation;
145     }
146
147     public void updateFilterRepresentations(Collection<FilterRepresentation> reps) {
148         for (FilterRepresentation r : reps) {
149             updateOrAddFilterRepresentation(r);
150         }
151     }
152
153     public void updateOrAddFilterRepresentation(FilterRepresentation rep) {
154         int pos = getPositionForRepresentation(rep);
155         if (pos != -1) {
156             mFilters.elementAt(pos).useParametersFrom(rep);
157         } else {
158             addFilter(rep.copy());
159         }
160     }
161
162     public void setDoApplyGeometry(boolean value) {
163         mDoApplyGeometry = value;
164     }
165
166     public void setDoApplyFilters(boolean value) {
167         mDoApplyFilters = value;
168     }
169
170     public boolean getDoApplyFilters() {
171         return mDoApplyFilters;
172     }
173
174     public boolean hasModifications() {
175         for (int i = 0; i < mFilters.size(); i++) {
176             FilterRepresentation filter = mFilters.elementAt(i);
177             if (!filter.isNil()) {
178                 return true;
179             }
180         }
181         return false;
182     }
183
184     public boolean contains(byte type) {
185         for (FilterRepresentation representation : mFilters) {
186             if (representation.getFilterType() == type
187                     && !representation.isNil()) {
188                 return true;
189             }
190         }
191         return false;
192     }
193
194     public boolean isPanoramaSafe() {
195         for (FilterRepresentation representation : mFilters) {
196             if (representation.getFilterType() == FilterRepresentation.TYPE_GEOMETRY
197                     && !representation.isNil()) {
198                 return false;
199             }
200             if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER
201                     && !representation.isNil()) {
202                 return false;
203             }
204             if (representation.getFilterType() == FilterRepresentation.TYPE_VIGNETTE
205                     && !representation.isNil()) {
206                 return false;
207             }
208             if (representation.getFilterType() == FilterRepresentation.TYPE_TINYPLANET
209                     && !representation.isNil()) {
210                 return false;
211             }
212         }
213         return true;
214     }
215
216     public boolean same(ImagePreset preset) {
217         if (preset == null) {
218             return false;
219         }
220
221         if (preset.mFilters.size() != mFilters.size()) {
222             return false;
223         }
224
225         if (mDoApplyGeometry != preset.mDoApplyGeometry) {
226             return false;
227         }
228
229         if (mDoApplyFilters != preset.mDoApplyFilters) {
230             if (mFilters.size() > 0 || preset.mFilters.size() > 0) {
231                 return false;
232             }
233         }
234
235         if (mDoApplyFilters && preset.mDoApplyFilters) {
236             for (int i = 0; i < preset.mFilters.size(); i++) {
237                 FilterRepresentation a = preset.mFilters.elementAt(i);
238                 FilterRepresentation b = mFilters.elementAt(i);
239
240                 if (!a.same(b)) {
241                     return false;
242                 }
243             }
244         }
245
246         return true;
247     }
248
249     public boolean equals(ImagePreset preset) {
250         if (preset == null) {
251             return false;
252         }
253
254         if (preset.mFilters.size() != mFilters.size()) {
255             return false;
256         }
257
258         if (mDoApplyGeometry != preset.mDoApplyGeometry) {
259             return false;
260         }
261
262         if (mDoApplyFilters != preset.mDoApplyFilters) {
263             if (mFilters.size() > 0 || preset.mFilters.size() > 0) {
264                 return false;
265             }
266         }
267
268         for (int i = 0; i < preset.mFilters.size(); i++) {
269             FilterRepresentation a = preset.mFilters.elementAt(i);
270             FilterRepresentation b = mFilters.elementAt(i);
271
272             if (!a.equals(b)) {
273                 return false;
274             }
275         }
276
277         return true;
278     }
279
280     public int similarUpTo(ImagePreset preset) {
281         for (int i = 0; i < preset.mFilters.size(); i++) {
282             FilterRepresentation a = preset.mFilters.elementAt(i);
283             if (i < mFilters.size()) {
284                 FilterRepresentation b = mFilters.elementAt(i);
285                 if (!a.same(b)) {
286                     return i;
287                 }
288                 if (!a.equals(b)) {
289                     return i;
290                 }
291             } else {
292                 return i;
293             }
294         }
295         return preset.mFilters.size();
296     }
297
298     public void showFilters() {
299         Log.v(LOGTAG, "\\\\\\ showFilters -- " + mFilters.size() + " filters");
300         int n = 0;
301         for (FilterRepresentation representation : mFilters) {
302             Log.v(LOGTAG, " filter " + n + " : " + representation.toString());
303             n++;
304         }
305         Log.v(LOGTAG, "/// showFilters -- " + mFilters.size() + " filters");
306     }
307
308     public FilterRepresentation getLastRepresentation() {
309         if (mFilters.size() > 0) {
310             return mFilters.lastElement();
311         }
312         return null;
313     }
314
315     public void removeFilter(FilterRepresentation filterRepresentation) {
316         if (filterRepresentation.getFilterType() == FilterRepresentation.TYPE_BORDER) {
317             for (int i = 0; i < mFilters.size(); i++) {
318                 if (mFilters.elementAt(i).getFilterType()
319                 == filterRepresentation.getFilterType()) {
320                     mFilters.remove(i);
321                     break;
322                 }
323             }
324         } else {
325             for (int i = 0; i < mFilters.size(); i++) {
326                 if (sameSerializationName(mFilters.elementAt(i), filterRepresentation)) {
327                     mFilters.remove(i);
328                     break;
329                 }
330             }
331         }
332     }
333
334     // If the filter is an "None" effect or border, then just don't add this filter.
335     public void addFilter(FilterRepresentation representation) {
336         if (representation instanceof FilterUserPresetRepresentation) {
337             ImagePreset preset = ((FilterUserPresetRepresentation) representation).getImagePreset();
338             // user preset replace everything but geometry
339             mFilters.clear();
340             for (int i = 0; i < preset.nbFilters(); i++) {
341                 addFilter(preset.getFilterRepresentation(i));
342             }
343             mFilters.add(representation);
344         } else if (representation.getFilterType() == FilterRepresentation.TYPE_GEOMETRY) {
345             // Add geometry filter, removing duplicates and do-nothing operations.
346             for (int i = 0; i < mFilters.size(); i++) {
347                 if (sameSerializationName(representation, mFilters.elementAt(i))) {
348                     mFilters.remove(i);
349                 }
350             }
351             int index = 0;
352             for (; index < mFilters.size(); index++) {
353                 FilterRepresentation rep = mFilters.elementAt(index);
354                 if (rep.getFilterType() != FilterRepresentation.TYPE_GEOMETRY) {
355                     break;
356                 }
357             }
358             if (!representation.isNil()) {
359                 mFilters.insertElementAt(representation, index);
360             }
361         } else if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) {
362             removeFilter(representation);
363             if (!isNoneBorderFilter(representation)) {
364                 mFilters.add(representation);
365             }
366         } else if (representation.getFilterType() == FilterRepresentation.TYPE_FX) {
367             boolean found = false;
368             for (int i = 0; i < mFilters.size(); i++) {
369                 FilterRepresentation current = mFilters.elementAt(i);
370                 int type = current.getFilterType();
371                 if (found) {
372                     if (type != FilterRepresentation.TYPE_VIGNETTE) {
373                         mFilters.remove(i);
374                         continue;
375                     }
376                 }
377                 if (type == FilterRepresentation.TYPE_FX) {
378                     if (current instanceof FilterUserPresetRepresentation) {
379                         ImagePreset preset = ((FilterUserPresetRepresentation) current)
380                                 .getImagePreset();
381                         // If we had an existing user preset, let's remove all the presets that
382                         // were added by it
383                         for (int j = 0; j < preset.nbFilters(); j++) {
384                             FilterRepresentation rep = preset.getFilterRepresentation(j);
385                             int pos = getPositionForRepresentation(rep);
386                             if (pos != -1) {
387                                 mFilters.remove(pos);
388                             }
389                         }
390                         int pos = getPositionForRepresentation(current);
391                         if (pos != -1) {
392                             mFilters.remove(pos);
393                         } else {
394                             pos = 0;
395                         }
396                         if (!isNoneFxFilter(representation)) {
397                             mFilters.add(pos, representation);
398                         }
399
400                     } else {
401                         mFilters.remove(i);
402                         if (!isNoneFxFilter(representation)) {
403                             mFilters.add(i, representation);
404                         }
405                     }
406                     found = true;
407                 }
408             }
409             if (!found) {
410                 if (!isNoneFxFilter(representation)) {
411                     mFilters.add(representation);
412                 }
413             }
414         } else {
415             mFilters.add(representation);
416         }
417     }
418
419     private boolean isNoneBorderFilter(FilterRepresentation representation) {
420         return representation instanceof FilterImageBorderRepresentation &&
421                 ((FilterImageBorderRepresentation) representation).getDrawableResource() == 0;
422     }
423
424     private boolean isNoneFxFilter(FilterRepresentation representation) {
425         return representation instanceof FilterFxRepresentation &&
426                 ((FilterFxRepresentation) representation).getNameResource() == R.string.none;
427     }
428
429     public FilterRepresentation getRepresentation(FilterRepresentation filterRepresentation) {
430         for (int i = 0; i < mFilters.size(); i++) {
431             FilterRepresentation representation = mFilters.elementAt(i);
432             if (sameSerializationName(representation, filterRepresentation)) {
433                 return representation;
434             }
435         }
436         return null;
437     }
438
439     public Bitmap apply(Bitmap original, FilterEnvironment environment) {
440         Bitmap bitmap = original;
441         bitmap = applyFilters(bitmap, -1, -1, environment);
442         return applyBorder(bitmap, environment);
443     }
444
445     public Collection<FilterRepresentation> getGeometryFilters() {
446         ArrayList<FilterRepresentation> geometry = new ArrayList<FilterRepresentation>();
447         for (FilterRepresentation r : mFilters) {
448             if (r.getFilterType() == FilterRepresentation.TYPE_GEOMETRY) {
449                 geometry.add(r);
450             }
451         }
452         return geometry;
453     }
454
455     public FilterRepresentation getFilterWithSerializationName(String serializationName) {
456         for (FilterRepresentation r : mFilters) {
457             if (r != null) {
458                 if (sameSerializationName(r.getSerializationName(), serializationName)) {
459                     return r.copy();
460                 }
461             }
462         }
463         return null;
464     }
465
466     public Rect finalGeometryRect(int width, int height) {
467         return GeometryMathUtils.finalGeometryRect(width, height, getGeometryFilters());
468     }
469
470     public Bitmap applyGeometry(Bitmap bitmap, FilterEnvironment environment) {
471         // Apply any transform -- 90 rotate, flip, straighten, crop
472         // Returns a new bitmap.
473         if (mDoApplyGeometry) {
474             Bitmap bmp = GeometryMathUtils.applyGeometryRepresentations(
475                     getGeometryFilters(), bitmap);
476             if (bmp != bitmap) {
477                 environment.cache(bitmap);
478             }
479             return bmp;
480         }
481         return bitmap;
482     }
483
484     public Bitmap applyBorder(Bitmap bitmap, FilterEnvironment environment) {
485         // get the border from the list of filters.
486         FilterRepresentation border = getFilterRepresentationForType(
487                 FilterRepresentation.TYPE_BORDER);
488         if (border != null && mDoApplyGeometry) {
489             bitmap = environment.applyRepresentation(border, bitmap);
490             if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) {
491                 UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR,
492                         "SaveBorder", border.getSerializationName(), 1);
493             }
494         }
495         return bitmap;
496     }
497
498     public int nbFilters() {
499         return mFilters.size();
500     }
501
502     public Bitmap applyFilters(Bitmap bitmap, int from, int to, FilterEnvironment environment) {
503         if (mDoApplyFilters) {
504             if (from < 0) {
505                 from = 0;
506             }
507             if (to == -1) {
508                 to = mFilters.size();
509             }
510             if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) {
511                 UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR,
512                         "SaveFilters", "Total", to - from + 1);
513             }
514             for (int i = from; i < to; i++) {
515                 FilterRepresentation representation = mFilters.elementAt(i);
516                 if (representation.getFilterType() == FilterRepresentation.TYPE_GEOMETRY) {
517                     // skip the geometry as it's already applied.
518                     continue;
519                 }
520                 if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) {
521                     // for now, let's skip the border as it will be applied in
522                     // applyBorder()
523                     // TODO: might be worth getting rid of applyBorder.
524                     continue;
525                 }
526                 Bitmap tmp = bitmap;
527                 bitmap = environment.applyRepresentation(representation, bitmap);
528                 if (tmp != bitmap) {
529                     environment.cache(tmp);
530                 }
531                 if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) {
532                     UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR,
533                             "SaveFilter", representation.getSerializationName(), 1);
534                 }
535                 if (environment.needsStop()) {
536                     return bitmap;
537                 }
538             }
539         }
540
541         return bitmap;
542     }
543
544     public void applyBorder(Allocation in, Allocation out,
545             boolean copyOut, FilterEnvironment environment) {
546         FilterRepresentation border = getFilterRepresentationForType(
547                 FilterRepresentation.TYPE_BORDER);
548         if (border != null && mDoApplyGeometry) {
549             // TODO: should keep the bitmap around
550             Allocation bitmapIn = in;
551             if (copyOut) {
552                 bitmapIn = Allocation.createTyped(
553                         CachingPipeline.getRenderScriptContext(), in.getType());
554                 bitmapIn.copyFrom(out);
555             }
556             environment.applyRepresentation(border, bitmapIn, out);
557         }
558     }
559
560     public void applyFilters(int from, int to, Allocation in, Allocation out,
561             FilterEnvironment environment) {
562         if (mDoApplyFilters) {
563             if (from < 0) {
564                 from = 0;
565             }
566             if (to == -1) {
567                 to = mFilters.size();
568             }
569             for (int i = from; i < to; i++) {
570                 FilterRepresentation representation = mFilters.elementAt(i);
571                 if (representation.getFilterType() == FilterRepresentation.TYPE_GEOMETRY
572                         || representation.getFilterType() == FilterRepresentation.TYPE_BORDER) {
573                     continue;
574                 }
575                 if (i > from) {
576                     in.copyFrom(out);
577                 }
578                 environment.applyRepresentation(representation, in, out);
579             }
580         }
581     }
582
583     public boolean canDoPartialRendering() {
584         if (MasterImage.getImage().getZoomOrientation() != ImageLoader.ORI_NORMAL) {
585             return false;
586         }
587         for (int i = 0; i < mFilters.size(); i++) {
588             FilterRepresentation representation = mFilters.elementAt(i);
589             if (!representation.supportsPartialRendering()) {
590                 return false;
591             }
592         }
593         return true;
594     }
595
596     public void fillImageStateAdapter(StateAdapter imageStateAdapter) {
597         if (imageStateAdapter == null) {
598             return;
599         }
600         Vector<State> states = new Vector<State>();
601         for (FilterRepresentation filter : mFilters) {
602             if (filter instanceof FilterUserPresetRepresentation) {
603                 // do not show the user preset itself in the state panel
604                 continue;
605             }
606             State state = new State(filter.getName());
607             state.setFilterRepresentation(filter);
608             states.add(state);
609         }
610         imageStateAdapter.fill(states);
611     }
612
613     public void setPartialRendering(boolean partialRendering, Rect bounds) {
614         mPartialRendering = partialRendering;
615         mPartialRenderingBounds = bounds;
616     }
617
618     public boolean isPartialRendering() {
619         return mPartialRendering;
620     }
621
622     public Rect getPartialRenderingBounds() {
623         return mPartialRenderingBounds;
624     }
625
626     public Vector<ImageFilter> getUsedFilters(BaseFiltersManager filtersManager) {
627         Vector<ImageFilter> usedFilters = new Vector<ImageFilter>();
628         for (int i = 0; i < mFilters.size(); i++) {
629             FilterRepresentation representation = mFilters.elementAt(i);
630             ImageFilter filter = filtersManager.getFilterForRepresentation(representation);
631             usedFilters.add(filter);
632         }
633         return usedFilters;
634     }
635
636     public String getJsonString(String name) {
637         StringWriter swriter = new StringWriter();
638         try {
639             JsonWriter writer = new JsonWriter(swriter);
640             writeJson(writer, name);
641             writer.close();
642         } catch (IOException e) {
643             return null;
644         }
645         return swriter.toString();
646     }
647
648     public void writeJson(JsonWriter writer, String name) {
649         int numFilters = mFilters.size();
650         try {
651             writer.beginObject();
652             for (int i = 0; i < numFilters; i++) {
653                 FilterRepresentation filter = mFilters.get(i);
654                 if (filter instanceof FilterUserPresetRepresentation) {
655                     continue;
656                 }
657                 String sname = filter.getSerializationName();
658                 if (DEBUG) {
659                     Log.v(LOGTAG, "Serialization: " + sname);
660                     if (sname == null) {
661                         Log.v(LOGTAG, "Serialization name null for filter: " + filter);
662                     }
663                 }
664                 writer.name(sname);
665                 filter.serializeRepresentation(writer);
666             }
667             writer.endObject();
668
669         } catch (IOException e) {
670            Log.e(LOGTAG,"Error encoding JASON",e);
671         }
672     }
673
674     /**
675      * populates preset from JSON string
676      *
677      * @param filterString a JSON string
678      * @return true on success if false ImagePreset is undefined
679      */
680     public boolean readJsonFromString(String filterString) {
681         if (DEBUG) {
682             Log.v(LOGTAG, "reading preset: \"" + filterString + "\"");
683         }
684         StringReader sreader = new StringReader(filterString);
685         try {
686             JsonReader reader = new JsonReader(sreader);
687             boolean ok = readJson(reader);
688             if (!ok) {
689                 reader.close();
690                 return false;
691             }
692             reader.close();
693         } catch (Exception e) {
694             Log.e(LOGTAG, "parsing the filter parameters:", e);
695             return false;
696         }
697         return true;
698     }
699
700     /**
701      * populates preset from JSON stream
702      *
703      * @param sreader a JSON string
704      * @return true on success if false ImagePreset is undefined
705      */
706     public boolean readJson(JsonReader sreader) throws IOException {
707         sreader.beginObject();
708
709         while (sreader.hasNext()) {
710             String name = sreader.nextName();
711             FilterRepresentation filter = creatFilterFromName(name);
712             if (filter == null) {
713                 Log.w(LOGTAG, "UNKNOWN FILTER! " + name);
714                 return false;
715             }
716             filter.deSerializeRepresentation(sreader);
717             addFilter(filter);
718         }
719         sreader.endObject();
720         return true;
721     }
722
723     FilterRepresentation creatFilterFromName(String name) {
724         if (FilterRotateRepresentation.SERIALIZATION_NAME.equals(name)) {
725             return new FilterRotateRepresentation();
726         } else if (FilterMirrorRepresentation.SERIALIZATION_NAME.equals(name)) {
727             return new FilterMirrorRepresentation();
728         } else if (FilterStraightenRepresentation.SERIALIZATION_NAME.equals(name)) {
729             return new FilterStraightenRepresentation();
730         } else if (FilterCropRepresentation.SERIALIZATION_NAME.equals(name)) {
731             return new FilterCropRepresentation();
732         }
733         FiltersManager filtersManager = FiltersManager.getManager();
734         return filtersManager.createFilterFromName(name);
735     }
736
737     public void updateWith(ImagePreset preset) {
738         if (preset.mFilters.size() != mFilters.size()) {
739             Log.e(LOGTAG, "Updating a preset with an incompatible one");
740             return;
741         }
742         for (int i = 0; i < mFilters.size(); i++) {
743             FilterRepresentation destRepresentation = mFilters.elementAt(i);
744             FilterRepresentation sourceRepresentation = preset.mFilters.elementAt(i);
745             destRepresentation.useParametersFrom(sourceRepresentation);
746         }
747     }
748 }