OSDN Git Service

Implements Redeye fix
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / filters / ImageFilterRedEye.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.filters;
18
19 import android.graphics.Bitmap;
20 import android.graphics.Matrix;
21 import android.graphics.RectF;
22
23 import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
24
25 import java.util.Vector;
26
27 public class ImageFilterRedEye extends ImageFilter {
28     private static final String LOGTAG = "ImageFilterRedEye";
29     private Vector<RedEyeCandidate> mCandidates = null;
30
31     public ImageFilterRedEye() {
32         mName = "Red Eye";
33     }
34
35     @Override
36     public ImageFilter clone() throws CloneNotSupportedException {
37         ImageFilterRedEye filter = (ImageFilterRedEye) super.clone();
38         if (mCandidates != null) {
39             int size = mCandidates.size();
40             filter.mCandidates = new Vector<RedEyeCandidate>();
41             for (int i = 0; i < size; i++) {
42                 filter.mCandidates.add(new RedEyeCandidate(mCandidates.elementAt(i)));
43             }
44         }
45         return filter;
46     }
47
48     @Override
49     public boolean isNil() {
50         if (mCandidates != null && mCandidates.size() > 0) {
51             return false;
52         }
53         return true;
54     }
55
56     @Override
57     public boolean same(ImageFilter filter) {
58         boolean isRedEyeFilter = super.same(filter);
59         if (!isRedEyeFilter) {
60             return false;
61         }
62         ImageFilterRedEye redEyeFilter = (ImageFilterRedEye) filter;
63         if (redEyeFilter.mCandidates == null && mCandidates == null) {
64             return true;
65         }
66         if (redEyeFilter.mCandidates == null || mCandidates == null) {
67             return false;
68         }
69         if (redEyeFilter.mCandidates.size() != mCandidates.size()) {
70             return false;
71         }
72         int size = mCandidates.size();
73         for (int i = 0; i < size; i++) {
74             RedEyeCandidate c1 = mCandidates.elementAt(i);
75             RedEyeCandidate c2 = redEyeFilter.mCandidates.elementAt(i);
76             if (!c1.equals(c2)) {
77                 return false;
78             }
79         }
80         return true;
81     }
82
83     public Vector<RedEyeCandidate> getCandidates() {
84         if (mCandidates == null) {
85             mCandidates = new Vector<RedEyeCandidate>();
86         }
87         return mCandidates;
88     }
89
90     public void addRect(RectF rect, RectF bounds) {
91         if (mCandidates == null) {
92             mCandidates = new Vector<RedEyeCandidate>();
93         }
94         Vector<RedEyeCandidate> intersects = new Vector<RedEyeCandidate>();
95         for (int i = 0; i < mCandidates.size(); i++) {
96             RedEyeCandidate r = mCandidates.elementAt(i);
97             if (r.intersect(rect)) {
98                 intersects.add(r);
99             }
100         }
101         for (int i = 0; i < intersects.size(); i++) {
102             RedEyeCandidate r = intersects.elementAt(i);
103             rect.union(r.mRect);
104             bounds.union(r.mBounds);
105             mCandidates.remove(r);
106         }
107         mCandidates.add(new RedEyeCandidate(rect, bounds));
108     }
109
110     public void clear() {
111         if (mCandidates == null) {
112             mCandidates = new Vector<RedEyeCandidate>();
113         }
114         mCandidates.clear();
115     }
116
117     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, short[] matrix);
118
119     @Override
120     public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
121         int w = bitmap.getWidth();
122         int h = bitmap.getHeight();
123         short[] rect = new short[4];
124
125         if (mCandidates != null && mCandidates.size() > 0) {
126             for (int i = 0; i < mCandidates.size(); i++) {
127                 RectF r = new RectF(mCandidates.elementAt(i).mRect);
128                 GeometryMetadata geo = getImagePreset().mGeoData;
129                 Matrix originalToScreen = geo.getOriginalToScreen(true,
130                         getImagePreset().getImageLoader().getOriginalBounds().width(),
131                         getImagePreset().getImageLoader().getOriginalBounds().height(),
132                         w, h);
133                 originalToScreen.mapRect(r);
134                 if (r.left < 0) {
135                     r.left = 0;
136                 }
137                 if (r.left > w) {
138                     r.left = w;
139                 }
140                 if (r.top < 0) {
141                     r.top = 0;
142                 }
143                 if (r.top > h) {
144                     r.top = h;
145                 }
146                 if (r.right < 0) {
147                     r.right = 0;
148                 }
149                 if (r.right > w) {
150                     r.right = w;
151                 }
152                 if (r.bottom < 0) {
153                     r.bottom = 0;
154                 }
155                 if (r.bottom > h) {
156                     r.bottom = h;
157                 }
158                 rect[0] = (short) r.left;
159                 rect[1] = (short) r.top;
160                 rect[2] = (short) r.width();
161                 rect[3] = (short) r.height();
162                 nativeApplyFilter(bitmap, w, h, rect);
163             }
164         }
165         return bitmap;
166     }
167 }