]> Pileus Git - ~andy/freeotp/blob - src/com/google/zxing/LuminanceSource.java
Add native camera support
[~andy/freeotp] / src / com / google / zxing / LuminanceSource.java
1 /*
2  * Copyright 2009 ZXing authors
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;
18
19 /**
20  * The purpose of this class hierarchy is to abstract different bitmap implementations across
21  * platforms into a standard interface for requesting greyscale luminance values. The interface
22  * only provides immutable methods; therefore crop and rotation create copies. This is to ensure
23  * that one Reader does not modify the original luminance source and leave it in an unknown state
24  * for other Readers in the chain.
25  *
26  * @author dswitkin@google.com (Daniel Switkin)
27  */
28 public abstract class LuminanceSource {
29
30   private final int width;
31   private final int height;
32
33   protected LuminanceSource(int width, int height) {
34     this.width = width;
35     this.height = height;
36   }
37
38   /**
39    * Fetches one row of luminance data from the underlying platform's bitmap. Values range from
40    * 0 (black) to 255 (white). Because Java does not have an unsigned byte type, callers will have
41    * to bitwise and with 0xff for each value. It is preferable for implementations of this method
42    * to only fetch this row rather than the whole image, since no 2D Readers may be installed and
43    * getMatrix() may never be called.
44    *
45    * @param y The row to fetch, 0 <= y < getHeight().
46    * @param row An optional preallocated array. If null or too small, it will be ignored.
47    *            Always use the returned object, and ignore the .length of the array.
48    * @return An array containing the luminance data.
49    */
50   public abstract byte[] getRow(int y, byte[] row);
51
52   /**
53    * Fetches luminance data for the underlying bitmap. Values should be fetched using:
54    * int luminance = array[y * width + x] & 0xff;
55    *
56    * @return A row-major 2D array of luminance values. Do not use result.length as it may be
57    *         larger than width * height bytes on some platforms. Do not modify the contents
58    *         of the result.
59    */
60   public abstract byte[] getMatrix();
61
62   /**
63    * @return The width of the bitmap.
64    */
65   public final int getWidth() {
66     return width;
67   }
68
69   /**
70    * @return The height of the bitmap.
71    */
72   public final int getHeight() {
73     return height;
74   }
75
76   /**
77    * @return Whether this subclass supports cropping.
78    */
79   public boolean isCropSupported() {
80     return false;
81   }
82
83   /**
84    * Returns a new object with cropped image data. Implementations may keep a reference to the
85    * original data rather than a copy. Only callable if isCropSupported() is true.
86    *
87    * @param left The left coordinate, 0 <= left < getWidth().
88    * @param top The top coordinate, 0 <= top <= getHeight().
89    * @param width The width of the rectangle to crop.
90    * @param height The height of the rectangle to crop.
91    * @return A cropped version of this object.
92    */
93   public LuminanceSource crop(int left, int top, int width, int height) {
94     throw new UnsupportedOperationException("This luminance source does not support cropping.");
95   }
96
97   /**
98    * @return Whether this subclass supports counter-clockwise rotation.
99    */
100   public boolean isRotateSupported() {
101     return false;
102   }
103
104   /**
105    * @return a wrapper of this {@code LuminanceSource} which inverts the luminances it returns -- black becomes
106    *  white and vice versa, and each value becomes (255-value).
107    */
108   public LuminanceSource invert() {
109     return new InvertedLuminanceSource(this);
110   }
111
112   /**
113    * Returns a new object with rotated image data by 90 degrees counterclockwise.
114    * Only callable if {@link #isRotateSupported()} is true.
115    *
116    * @return A rotated version of this object.
117    */
118   public LuminanceSource rotateCounterClockwise() {
119     throw new UnsupportedOperationException("This luminance source does not support rotation by 90 degrees.");
120   }
121
122   /**
123    * Returns a new object with rotated image data by 45 degrees counterclockwise.
124    * Only callable if {@link #isRotateSupported()} is true.
125    *
126    * @return A rotated version of this object.
127    */
128   public LuminanceSource rotateCounterClockwise45() {
129     throw new UnsupportedOperationException("This luminance source does not support rotation by 45 degrees.");
130   }
131
132   @Override
133   public final String toString() {
134     byte[] row = new byte[width];
135     StringBuilder result = new StringBuilder(height * (width + 1));
136     for (int y = 0; y < height; y++) {
137       row = getRow(y, row);
138       for (int x = 0; x < width; x++) {
139         int luminance = row[x] & 0xFF;
140         char c;
141         if (luminance < 0x40) {
142           c = '#';
143         } else if (luminance < 0x80) {
144           c = '+';
145         } else if (luminance < 0xC0) {
146           c = '.';
147         } else {
148           c = ' ';
149         }
150         result.append(c);
151       }
152       result.append('\n');
153     }
154     return result.toString();
155   }
156
157 }