Committed C# port from Mohamad
[zxing.git] / csharp / common / BitMatrix.cs
1 /*\r
2 * Copyright 2008 ZXing authors\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 namespace com.google.zxing.common\r
17 {\r
18     using System;\r
19     using System.Text;\r
20 \r
21     /// <summary> A class which wraps a 2D array of bytes. The default usage is signed. If you want to use it as a\r
22     /// unsigned container, it's up to you to do byteValue & 0xff at each location.\r
23     /// *\r
24     /// JAVAPORT: I'm not happy about the argument ordering throughout the file, as I always like to have\r
25     /// the horizontal component first, but this is for compatibility with the C++ code. The original\r
26     /// code was a 2D array of ints, but since it only ever gets assigned -1, 0, and 1, I'm going to use\r
27     /// less memory and go with bytes.\r
28     /// *\r
29     /// </summary>\r
30     /// <author>  dswitkin@google.com (Daniel Switkin)\r
31     /// \r
32     /// </author>\r
33     public sealed class BitMatrix\r
34     {\r
35           private int dimension;\r
36           private int[] bits;\r
37 \r
38           public BitMatrix(int dimension) {\r
39             if (dimension < 1) {\r
40               throw new Exception("dimension must be at least 1");\r
41             }\r
42             this.dimension = dimension;\r
43             int numBits = dimension * dimension;\r
44             int arraySize = numBits >> 5; // one int per 32 bits\r
45             if ((numBits & 0x1F) != 0) { // plus one more if there are leftovers\r
46               arraySize++;\r
47             }\r
48             bits = new int[arraySize];\r
49           }\r
50 \r
51           /**\r
52            * @param i row offset\r
53            * @param j column offset\r
54            * @return value of given bit in matrix\r
55            */\r
56           public bool get(int i, int j) {\r
57             int offset = i + dimension * j;\r
58             //return ((bits[offset >> 5] >>> (offset & 0x1F)) & 0x01) != 0;\r
59                         return ((SupportClass.URShift(bits[offset >> 5], (offset & 0x1F))) & 0x01) != 0;\r
60           }\r
61 \r
62           /**\r
63            * <p>Sets the given bit to true.</p>\r
64            *\r
65            * @param i row offset\r
66            * @param j column offset\r
67            */\r
68           public void set(int i, int j) {\r
69             int offset = i + dimension * j;\r
70             bits[offset >> 5] |= 1 << (offset & 0x1F);\r
71           }\r
72 \r
73           /**\r
74            * <p>Sets a square region of the bit matrix to true.</p>\r
75            *\r
76            * @param topI row offset of region's top-left corner (inclusive)\r
77            * @param leftJ column offset of region's top-left corner (inclusive)\r
78            * @param height height of region\r
79            * @param width width of region\r
80            */\r
81           public void setRegion(int topI, int leftJ, int height, int width) {\r
82             if (topI < 0 || leftJ < 0) {\r
83               throw new Exception("topI and leftJ must be nonnegative");\r
84             }\r
85             if (height < 1 || width < 1) {\r
86                 throw new Exception("height and width must be at least 1");\r
87             }\r
88             int maxJ = leftJ + width;\r
89             int maxI = topI + height;\r
90             if (maxI > dimension || maxJ > dimension) {\r
91                 throw new Exception(\r
92                   "topI + height and leftJ + width must be <= matrix dimension");\r
93             }\r
94             for (int j = leftJ; j < maxJ; j++) {\r
95               int jOffset = dimension * j;\r
96               for (int i = topI; i < maxI; i++) {\r
97                 int offset = i + jOffset;\r
98                 bits[offset >> 5] |= 1 << (offset & 0x1F);\r
99               }\r
100             }\r
101           }\r
102 \r
103           /**\r
104            * @return row/column dimension of this matrix\r
105            */\r
106           public int getDimension() {\r
107             return dimension;\r
108           }\r
109 \r
110           /**\r
111            * @return array of ints holding internal representation of this matrix's bits\r
112            */\r
113           public int[] getBits() {\r
114             return bits;\r
115           }\r
116 \r
117           public String toString() {\r
118               StringBuilder result = new StringBuilder(dimension * (dimension + 1));\r
119             for (int i = 0; i < dimension; i++) {\r
120               for (int j = 0; j < dimension; j++) {\r
121                 result.Append(get(i, j) ? "X " : "  ");\r
122               }\r
123               result.Append('\n');\r
124             }\r
125             return result.ToString();\r
126           }\r
127    \r
128     }\r
129 }