Improved GridSampler API -- no need for reflection anymore. Reintroduced Android...
[zxing.git] / android / src / com / google / zxing / client / android / AndroidGraphicsGridSampler.java
1 /*
2  * Copyright 2007 Google Inc.
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.google.zxing.client.android;
18
19 import com.google.zxing.MonochromeBitmapSource;
20 import com.google.zxing.ReaderException;
21 import com.google.zxing.common.BitMatrix;
22 import com.google.zxing.qrcode.detector.AlignmentPattern;
23 import com.google.zxing.qrcode.detector.FinderPattern;
24 import com.google.zxing.qrcode.detector.GridSampler;
25
26 import android.graphics.Matrix;
27
28 /**
29  * Implementation based on Android's
30  * {@link Matrix#setPolyToPoly(float[], int, float[], int, int)}
31  * class, which should offer faster performance for these matrix
32  * operations.
33  * 
34  * @author srowen@google.com (Sean Owen)
35  */
36 public final class AndroidGraphicsGridSampler extends GridSampler {
37
38   @Override
39   protected BitMatrix sampleGrid(MonochromeBitmapSource image,
40                                  FinderPattern topLeft,
41                                  FinderPattern topRight,
42                                  FinderPattern bottomLeft,
43                                  AlignmentPattern alignmentPattern,
44                                  int dimension) throws ReaderException {
45     float dimMinusThree = (float) dimension - 3.5f;
46     float bottomRightX, bottomRightY;
47     float sourceBottomRightX, sourceBottomRightY;
48     if (alignmentPattern != null) {
49       bottomRightX = alignmentPattern.getX();
50       bottomRightY = alignmentPattern.getY();
51       sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
52     } else {
53       // Don't have an alignment pattern, just make up the bottom-right point
54       bottomRightX = (topRight.getX() - topLeft.getX()) + bottomLeft.getX();
55       bottomRightY = (topRight.getY() - topLeft.getY()) + bottomLeft.getY();
56       sourceBottomRightX = sourceBottomRightY = dimMinusThree;
57     }
58
59     Matrix transformMatrix = new Matrix();
60     boolean succeeded = transformMatrix.setPolyToPoly(
61       new float[] {
62         topLeft.getX(),
63         topLeft.getY(),
64         topRight.getX(),
65         topRight.getY(),
66         bottomLeft.getX(),
67         bottomLeft.getY(),
68         bottomRightX,
69         bottomRightY
70       },
71       0,
72       new float[] {
73         3.5f,
74         3.5f,
75         dimMinusThree,
76         3.5f,
77         3.5f,
78         dimMinusThree,
79         sourceBottomRightX,
80         sourceBottomRightY,
81       },
82       0,
83       4
84     );
85     if (!succeeded) {
86       throw new ReaderException("Could not establish transformation matrix");
87     }
88
89     BitMatrix bits = new BitMatrix(dimension);
90     float[] points = new float[dimension << 1];
91     for (int i = 0; i < dimension; i++) {
92       int max = points.length;
93       float iValue = (float) i + 0.5f;
94       for (int j = 0; j < max; j += 2) {
95         points[j] = (float) (j >> 1) + 0.5f;
96         points[j + 1] = iValue;
97       }
98       transformMatrix.mapPoints(points);
99       // Quick check to see if points transformed to something inside the image;
100       // sufficent to check the endpoints
101       checkEndpoint(image, points);
102       for (int j = 0; j < max; j += 2) {
103         if (image.isBlack((int) points[j], (int) points[j + 1])) {
104           // Black(-ish) pixel
105           bits.set(i, j >> 1);
106         }
107       }
108     }
109     return bits;
110   }
111
112 }