1 /*
2  * Copyright (C) 2013 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 package com.android.gallery3d.filtershow.filters;
17 
18 import android.content.Context;
19 import android.content.res.Resources;
20 import android.graphics.Color;
21 import android.util.Log;
22 
23 import com.android.gallery3d.R;
24 import com.android.gallery3d.filtershow.pipeline.ImagePreset;
25 
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.Vector;
29 
30 public abstract class BaseFiltersManager implements FiltersManagerInterface {
31     protected HashMap<Class, ImageFilter> mFilters = null;
32     protected HashMap<String, FilterRepresentation> mRepresentationLookup = null;
33     private static final String LOGTAG = "BaseFiltersManager";
34 
35     protected ArrayList<FilterRepresentation> mLooks = new ArrayList<FilterRepresentation>();
36     protected ArrayList<FilterRepresentation> mBorders = new ArrayList<FilterRepresentation>();
37     protected ArrayList<FilterRepresentation> mTools = new ArrayList<FilterRepresentation>();
38     protected ArrayList<FilterRepresentation> mEffects = new ArrayList<FilterRepresentation>();
39     private static int mImageBorderSize = 4; // in percent
40 
init()41     protected void init() {
42         mFilters = new HashMap<Class, ImageFilter>();
43         mRepresentationLookup = new HashMap<String, FilterRepresentation>();
44         Vector<Class> filters = new Vector<Class>();
45         addFilterClasses(filters);
46         for (Class filterClass : filters) {
47             try {
48                 Object filterInstance = filterClass.newInstance();
49                 if (filterInstance instanceof ImageFilter) {
50                     mFilters.put(filterClass, (ImageFilter) filterInstance);
51 
52                     FilterRepresentation rep =
53                         ((ImageFilter) filterInstance).getDefaultRepresentation();
54                     if (rep != null) {
55                         addRepresentation(rep);
56                     }
57                 }
58             } catch (InstantiationException e) {
59                 e.printStackTrace();
60             } catch (IllegalAccessException e) {
61                 e.printStackTrace();
62             }
63         }
64     }
65 
addRepresentation(FilterRepresentation rep)66     public void addRepresentation(FilterRepresentation rep) {
67         mRepresentationLookup.put(rep.getSerializationName(), rep);
68     }
69 
createFilterFromName(String name)70     public FilterRepresentation createFilterFromName(String name) {
71         try {
72             return mRepresentationLookup.get(name).copy();
73         } catch (Exception e) {
74             Log.v(LOGTAG, "unable to generate a filter representation for \"" + name + "\"");
75             e.printStackTrace();
76         }
77         return null;
78     }
79 
getFilter(Class c)80     public ImageFilter getFilter(Class c) {
81         return mFilters.get(c);
82     }
83 
84     @Override
getFilterForRepresentation(FilterRepresentation representation)85     public ImageFilter getFilterForRepresentation(FilterRepresentation representation) {
86         return mFilters.get(representation.getFilterClass());
87     }
88 
getRepresentation(Class c)89     public FilterRepresentation getRepresentation(Class c) {
90         ImageFilter filter = mFilters.get(c);
91         if (filter != null) {
92             return filter.getDefaultRepresentation();
93         }
94         return null;
95     }
96 
freeFilterResources(ImagePreset preset)97     public void freeFilterResources(ImagePreset preset) {
98         if (preset == null) {
99             return;
100         }
101         Vector<ImageFilter> usedFilters = preset.getUsedFilters(this);
102         for (Class c : mFilters.keySet()) {
103             ImageFilter filter = mFilters.get(c);
104             if (!usedFilters.contains(filter)) {
105                 filter.freeResources();
106             }
107         }
108     }
109 
freeRSFilterScripts()110     public void freeRSFilterScripts() {
111         for (Class c : mFilters.keySet()) {
112             ImageFilter filter = mFilters.get(c);
113             if (filter != null && filter instanceof ImageFilterRS) {
114                 ((ImageFilterRS) filter).resetScripts();
115             }
116         }
117     }
118 
addFilterClasses(Vector<Class> filters)119     protected void addFilterClasses(Vector<Class> filters) {
120         filters.add(ImageFilterTinyPlanet.class);
121         filters.add(ImageFilterRedEye.class);
122         filters.add(ImageFilterWBalance.class);
123         filters.add(ImageFilterExposure.class);
124         filters.add(ImageFilterVignette.class);
125         filters.add(ImageFilterGrad.class);
126         filters.add(ImageFilterContrast.class);
127         filters.add(ImageFilterShadows.class);
128         filters.add(ImageFilterHighlights.class);
129         filters.add(ImageFilterVibrance.class);
130         filters.add(ImageFilterSharpen.class);
131         filters.add(ImageFilterCurves.class);
132         filters.add(ImageFilterDraw.class);
133         filters.add(ImageFilterHue.class);
134         filters.add(ImageFilterChanSat.class);
135         filters.add(ImageFilterSaturated.class);
136         filters.add(ImageFilterBwFilter.class);
137         filters.add(ImageFilterNegative.class);
138         filters.add(ImageFilterEdge.class);
139         filters.add(ImageFilterKMeans.class);
140         filters.add(ImageFilterFx.class);
141         filters.add(ImageFilterBorder.class);
142         filters.add(ImageFilterColorBorder.class);
143     }
144 
getLooks()145     public ArrayList<FilterRepresentation> getLooks() {
146         return mLooks;
147     }
148 
getBorders()149     public ArrayList<FilterRepresentation> getBorders() {
150         return mBorders;
151     }
152 
getTools()153     public ArrayList<FilterRepresentation> getTools() {
154         return mTools;
155     }
156 
getEffects()157     public ArrayList<FilterRepresentation> getEffects() {
158         return mEffects;
159     }
160 
addBorders(Context context)161     public void addBorders(Context context) {
162 
163         // Do not localize
164         String[] serializationNames = {
165                 "FRAME_4X5",
166                 "FRAME_BRUSH",
167                 "FRAME_GRUNGE",
168                 "FRAME_SUMI_E",
169                 "FRAME_TAPE",
170                 "FRAME_BLACK",
171                 "FRAME_BLACK_ROUNDED",
172                 "FRAME_WHITE",
173                 "FRAME_WHITE_ROUNDED",
174                 "FRAME_CREAM",
175                 "FRAME_CREAM_ROUNDED"
176         };
177 
178         // The "no border" implementation
179         int i = 0;
180         FilterRepresentation rep = new FilterImageBorderRepresentation(0);
181         mBorders.add(rep);
182 
183         // Regular borders
184         ArrayList <FilterRepresentation> borderList = new ArrayList<FilterRepresentation>();
185 
186 
187         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_4x5);
188         borderList.add(rep);
189 
190         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_brush);
191         borderList.add(rep);
192 
193         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_grunge);
194         borderList.add(rep);
195 
196         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_sumi_e);
197         borderList.add(rep);
198 
199         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_tape);
200         borderList.add(rep);
201 
202         rep = new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize, 0);
203         borderList.add(rep);
204 
205         rep = new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize,
206                 mImageBorderSize);
207         borderList.add(rep);
208 
209         rep = new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize, 0);
210         borderList.add(rep);
211 
212         rep = new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize,
213                 mImageBorderSize);
214         borderList.add(rep);
215 
216         int creamColor = Color.argb(255, 237, 237, 227);
217         rep = new FilterColorBorderRepresentation(creamColor, mImageBorderSize, 0);
218         borderList.add(rep);
219 
220         rep = new FilterColorBorderRepresentation(creamColor, mImageBorderSize,
221                 mImageBorderSize);
222         borderList.add(rep);
223 
224         for (FilterRepresentation filter : borderList) {
225             filter.setSerializationName(serializationNames[i++]);
226             addRepresentation(filter);
227             mBorders.add(filter);
228         }
229 
230     }
231 
addLooks(Context context)232     public void addLooks(Context context) {
233         int[] drawid = {
234                 R.drawable.filtershow_fx_0005_punch,
235                 R.drawable.filtershow_fx_0000_vintage,
236                 R.drawable.filtershow_fx_0004_bw_contrast,
237                 R.drawable.filtershow_fx_0002_bleach,
238                 R.drawable.filtershow_fx_0001_instant,
239                 R.drawable.filtershow_fx_0007_washout,
240                 R.drawable.filtershow_fx_0003_blue_crush,
241                 R.drawable.filtershow_fx_0008_washout_color,
242                 R.drawable.filtershow_fx_0006_x_process
243         };
244 
245         int[] fxNameid = {
246                 R.string.ffx_punch,
247                 R.string.ffx_vintage,
248                 R.string.ffx_bw_contrast,
249                 R.string.ffx_bleach,
250                 R.string.ffx_instant,
251                 R.string.ffx_washout,
252                 R.string.ffx_blue_crush,
253                 R.string.ffx_washout_color,
254                 R.string.ffx_x_process
255         };
256 
257         // Do not localize.
258         String[] serializationNames = {
259                 "LUT3D_PUNCH",
260                 "LUT3D_VINTAGE",
261                 "LUT3D_BW",
262                 "LUT3D_BLEACH",
263                 "LUT3D_INSTANT",
264                 "LUT3D_WASHOUT",
265                 "LUT3D_BLUECRUSH",
266                 "LUT3D_WASHOUT_COLOR",
267                 "LUT3D_XPROCESS"
268         };
269 
270         FilterFxRepresentation nullFx =
271                 new FilterFxRepresentation(context.getString(R.string.none),
272                         0, R.string.none);
273         mLooks.add(nullFx);
274 
275         for (int i = 0; i < drawid.length; i++) {
276             FilterFxRepresentation fx = new FilterFxRepresentation(
277                     context.getString(fxNameid[i]), drawid[i], fxNameid[i]);
278             fx.setSerializationName(serializationNames[i]);
279             ImagePreset preset = new ImagePreset();
280             preset.addFilter(fx);
281             FilterUserPresetRepresentation rep = new FilterUserPresetRepresentation(
282                     context.getString(fxNameid[i]), preset, -1);
283             mLooks.add(rep);
284             addRepresentation(fx);
285         }
286     }
287 
addEffects()288     public void addEffects() {
289         mEffects.add(getRepresentation(ImageFilterTinyPlanet.class));
290         mEffects.add(getRepresentation(ImageFilterWBalance.class));
291         mEffects.add(getRepresentation(ImageFilterExposure.class));
292         mEffects.add(getRepresentation(ImageFilterVignette.class));
293         mEffects.add(getRepresentation(ImageFilterGrad.class));
294         mEffects.add(getRepresentation(ImageFilterContrast.class));
295         mEffects.add(getRepresentation(ImageFilterShadows.class));
296         mEffects.add(getRepresentation(ImageFilterHighlights.class));
297         mEffects.add(getRepresentation(ImageFilterVibrance.class));
298         mEffects.add(getRepresentation(ImageFilterSharpen.class));
299         mEffects.add(getRepresentation(ImageFilterCurves.class));
300         mEffects.add(getRepresentation(ImageFilterHue.class));
301         mEffects.add(getRepresentation(ImageFilterChanSat.class));
302         mEffects.add(getRepresentation(ImageFilterBwFilter.class));
303         mEffects.add(getRepresentation(ImageFilterNegative.class));
304         mEffects.add(getRepresentation(ImageFilterEdge.class));
305         mEffects.add(getRepresentation(ImageFilterKMeans.class));
306     }
307 
addTools(Context context)308     public void addTools(Context context) {
309 
310         int[] textId = {
311                 R.string.crop,
312                 R.string.straighten,
313                 R.string.rotate,
314                 R.string.mirror
315         };
316 
317         int[] overlayId = {
318                 R.drawable.filtershow_button_geometry_crop,
319                 R.drawable.filtershow_button_geometry_straighten,
320                 R.drawable.filtershow_button_geometry_rotate,
321                 R.drawable.filtershow_button_geometry_flip
322         };
323 
324         FilterRepresentation[] geometryFilters = {
325                 new FilterCropRepresentation(),
326                 new FilterStraightenRepresentation(),
327                 new FilterRotateRepresentation(),
328                 new FilterMirrorRepresentation()
329         };
330 
331         for (int i = 0; i < textId.length; i++) {
332             FilterRepresentation geometry = geometryFilters[i];
333             geometry.setTextId(textId[i]);
334             geometry.setOverlayId(overlayId[i]);
335             geometry.setOverlayOnly(true);
336             if (geometry.getTextId() != 0) {
337                 geometry.setName(context.getString(geometry.getTextId()));
338             }
339             mTools.add(geometry);
340         }
341 
342         //mTools.add(getRepresentation(ImageFilterRedEye.class));
343         mTools.add(getRepresentation(ImageFilterDraw.class));
344     }
345 
removeRepresentation(ArrayList<FilterRepresentation> list, FilterRepresentation representation)346     public void removeRepresentation(ArrayList<FilterRepresentation> list,
347                                           FilterRepresentation representation) {
348         for (int i = 0; i < list.size(); i++) {
349             FilterRepresentation r = list.get(i);
350             if (r.getFilterClass() == representation.getFilterClass()) {
351                 list.remove(i);
352                 break;
353             }
354         }
355     }
356 
setFilterResources(Resources resources)357     public void setFilterResources(Resources resources) {
358         ImageFilterBorder filterBorder = (ImageFilterBorder) getFilter(ImageFilterBorder.class);
359         filterBorder.setResources(resources);
360         ImageFilterFx filterFx = (ImageFilterFx) getFilter(ImageFilterFx.class);
361         filterFx.setResources(resources);
362     }
363 }
364