git-svn-id: http://zxing.googlecode.com/svn/trunk@2 59b500cc-1b3d-0410-9834-0bbf25fbcc57
[zxing.git] / src / com / google / zxing / common / BitMatrix.java
1 /*\r
2  * Copyright 2007 Google Inc.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package com.google.zxing.common;\r
18 \r
19 /**\r
20  * <p>Represnts a square matrix of bits. In function arguments below, i is the row position\r
21  * and j the column position of a bit. The top left bit corresponds to i = 0 and j = 0.</p>\r
22  *\r
23  * <p>Internally the bits are represented in a compact 1-D array of 32-bit ints. The\r
24  * ordering of bits is column-major; that is the bits in this array correspond to\r
25  * j=0 and i=0..dimension-1 first, then j=1 and i=0..dimension-1, etc.</p>\r
26  *\r
27  * <p>Within each int, less-signficant bits correspond to lower values of i and higher rows.\r
28  * That is, the top-left bit is the least significant bit of the first int.</p>\r
29  *\r
30  * <p>This class is a convenient wrapper around this representation, but also exposes the internal\r
31  * array for efficient access and manipulation.</p>\r
32  *\r
33  * @author srowen@google.com (Sean Owen)\r
34  */\r
35 public final class BitMatrix {\r
36 \r
37   private final int dimension;\r
38   private final int[] bits;\r
39 \r
40   public BitMatrix(int dimension) {\r
41     if (dimension < 1) {\r
42       throw new IllegalArgumentException("dimension must be at least 1");\r
43     }\r
44     this.dimension = dimension;\r
45     int numBits = dimension * dimension;\r
46     int arraySize = numBits >> 5; // one int per 32 bits\r
47     if ((numBits & 0x1F) != 0) { // plus one more if there are leftovers\r
48       arraySize++;\r
49     }\r
50     bits = new int[arraySize];\r
51   }\r
52 \r
53   public boolean get(int i, int j) {\r
54     int offset = i + dimension * j;\r
55     return ((bits[offset >> 5] >>> (offset & 0x1F)) & 0x01) != 0;\r
56   }\r
57 \r
58   public void set(int i, int j) {\r
59     int offset = i + dimension * j;\r
60     bits[offset >> 5] |= 1 << (offset & 0x1F);\r
61   }\r
62 \r
63   public void setRegion(int topI, int leftJ, int height, int width) {\r
64     if (topI < 0 || leftJ < 0) {\r
65       throw new IllegalArgumentException("topI and leftJ must be nonnegative");\r
66     }\r
67     if (height < 1 || width < 1) {\r
68       throw new IllegalArgumentException("height and width must be at least 1");\r
69     }\r
70     int maxJ = leftJ + width;\r
71     int maxI = topI + height;\r
72     if (maxI > dimension || maxJ > dimension) {\r
73       throw new IllegalArgumentException(\r
74           "topI + height and leftJ + width must be <= matrix dimension");\r
75     }\r
76     for (int j = leftJ; j < maxJ; j++) {\r
77       int jOffset = dimension * j;\r
78       for (int i = topI; i < maxI; i++) {\r
79         int offset = i + jOffset;\r
80         bits[offset >> 5] |= 1 << (offset & 0x1F);\r
81       }\r
82     }\r
83   }\r
84 \r
85   public int getDimension() {\r
86     return dimension;\r
87   }\r
88 \r
89   public int[] getBits() {\r
90     return bits;\r
91   }\r
92 \r
93   /*\r
94   public BufferedImage toBufferedImage() {\r
95                 BufferedImage image =\r
96                   new BufferedImage(dimension, dimension, BufferedImage.TYPE_BYTE_BINARY);\r
97                 for (int j = 0; j < dimension; j++) {\r
98                         for (int i = 0; i < dimension; i++) {\r
99                                 image.setRGB(j, i, get(i, j) ? 0x00000000 : 0x00FFFFFF);\r
100                         }\r
101                 }\r
102                 return image;\r
103         }\r
104          */\r
105 \r
106 }\r