1 /*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 - This software is distributed in the hope that it will be
4 - useful, but with NO WARRANTY OF ANY KIND.
5 - No author or distributor accepts responsibility to anyone for the
6 - consequences of using this software, or for whether it serves any
7 - particular purpose or works at all, unless he or she says so in
8 - writing. Everyone is granted permission to copy, modify and
9 - redistribute this source code, for commercial or non-commercial
10 - purposes, with the following restrictions: (1) the origin of this
11 - source code must not be misrepresented; (2) modified versions must
12 - be plainly marked as such; and (3) this notice may not be removed
13 - or altered from any source or modified source distribution.
14 *====================================================================*/
15
16 /*
17 * arrayaccess.c
18 *
19 * Access within an array of 32-bit words
20 *
21 * l_int32 l_getDataBit()
22 * void l_setDataBit()
23 * void l_clearDataBit()
24 * void l_setDataBitVal()
25 * l_int32 l_getDataDibit()
26 * void l_setDataDibit()
27 * void l_clearDataDibit()
28 * l_int32 l_getDataQbit()
29 * void l_setDataQbit()
30 * void l_clearDataQbit()
31 * l_int32 l_getDataByte()
32 * void l_setDataByte()
33 * l_int32 l_getDataTwoBytes()
34 * void l_setDataTwoBytes()
35 * l_int32 l_getDataFourBytes()
36 * void l_setDataFourBytes()
37 *
38 * Note that these all require 32-bit alignment, and hence an input
39 * ptr to l_uint32. However, this is not enforced by the compiler.
40 * Instead, we allow the use of a void* ptr, because the line ptrs
41 * are an efficient way to get random access (see pixGetLinePtrs()).
42 * It is then necessary to cast internally within each function
43 * because ptr arithmetic requires knowing the size of the units
44 * being referenced.
45 */
46
47 #include <stdio.h>
48 #include "allheaders.h"
49
50
51 /*----------------------------------------------------------------------*
52 * Access within an array of 32-bit words *
53 *----------------------------------------------------------------------*/
54 /*!
55 * l_getDataBit()
56 *
57 * Input: line (ptr to beginning of data line)
58 * n (pixel index)
59 * Return: val of the nth (1-bit) pixel.
60 */
61 l_int32
l_getDataBit(void * line,l_int32 n)62 l_getDataBit(void *line,
63 l_int32 n)
64 {
65 return (*((l_uint32 *)line + (n >> 5)) >> (31 - (n & 31))) & 1;
66 }
67
68
69 /*!
70 * l_setDataBit()
71 *
72 * Input: line (ptr to beginning of data line)
73 * n (pixel index)
74 * Return: void
75 *
76 * Action: sets the pixel to 1
77 */
78 void
l_setDataBit(void * line,l_int32 n)79 l_setDataBit(void *line,
80 l_int32 n)
81 {
82 *((l_uint32 *)line + (n >> 5)) |= (0x80000000 >> (n & 31));
83 }
84
85
86 /*!
87 * l_clearDataBit()
88 *
89 * Input: line (ptr to beginning of data line)
90 * n (pixel index)
91 * Return: void
92 *
93 * Action: sets the (1-bit) pixel to 0
94 */
95 void
l_clearDataBit(void * line,l_int32 n)96 l_clearDataBit(void *line,
97 l_int32 n)
98 {
99 *((l_uint32 *)line + (n >> 5)) &= ~(0x80000000 >> (n & 31));
100 }
101
102
103 /*!
104 * l_setDataBitVal()
105 *
106 * Input: line (ptr to beginning of data line)
107 * n (pixel index)
108 * val (val to be inserted: 0 - 3)
109 * Return: void
110 *
111 * Notes:
112 * (1) This is actually a little slower than using:
113 * if (val == 0)
114 * l_ClearDataBit(line, n);
115 * else
116 * l_SetDataBit(line, n);
117 */
118 void
l_setDataBitVal(void * line,l_int32 n,l_int32 val)119 l_setDataBitVal(void *line,
120 l_int32 n,
121 l_int32 val)
122 {
123 l_uint32 *pword;
124
125 pword = (l_uint32 *)line + (n >> 5);
126 *pword &= ~(0x80000000 >> (n & 31)); /* clear */
127 *pword |= val << (31 - (n & 31)); /* set */
128 return;
129 }
130
131
132 /*!
133 * l_getDataDibit()
134 *
135 * Input: line (ptr to beginning of data line)
136 * n (pixel index)
137 * Return: val of the nth (2-bit) pixel.
138 */
139 l_int32
l_getDataDibit(void * line,l_int32 n)140 l_getDataDibit(void *line,
141 l_int32 n)
142 {
143 return (*((l_uint32 *)line + (n >> 4)) >> (2 * (15 - (n & 15)))) & 3;
144 }
145
146
147 /*!
148 * l_setDataDibit()
149 *
150 * Input: line (ptr to beginning of data line)
151 * n (pixel index)
152 * val (val to be inserted: 0 - 3)
153 * Return: void
154 */
155 void
l_setDataDibit(void * line,l_int32 n,l_int32 val)156 l_setDataDibit(void *line,
157 l_int32 n,
158 l_int32 val)
159 {
160 l_uint32 *pword;
161
162 pword = (l_uint32 *)line + (n >> 4);
163 *pword &= ~(0xc0000000 >> (2 * (n & 15))); /* clear */
164 *pword |= val << (30 - 2 * (n & 15)); /* set */
165 return;
166 }
167
168
169 /*!
170 * l_clearDataDibit()
171 *
172 * Input: line (ptr to beginning of data line)
173 * n (pixel index)
174 * Return: void
175 *
176 * Action: sets the (2-bit) pixel to 0
177 */
178 void
l_clearDataDibit(void * line,l_int32 n)179 l_clearDataDibit(void *line,
180 l_int32 n)
181 {
182 *((l_uint32 *)line + (n >> 4)) &= ~(0xc0000000 >> (2 * (n & 15)));
183 }
184
185
186 /*!
187 * l_getDataQbit()
188 *
189 * Input: line (ptr to beginning of data line)
190 * n (pixel index)
191 * Return: val of the nth (4-bit) pixel.
192 */
193 l_int32
l_getDataQbit(void * line,l_int32 n)194 l_getDataQbit(void *line,
195 l_int32 n)
196 {
197 return (*((l_uint32 *)line + (n >> 3)) >> (4 * (7 - (n & 7)))) & 0xf;
198 }
199
200
201 /*!
202 * l_setDataQbit()
203 *
204 * Input: line (ptr to beginning of data line)
205 * n (pixel index)
206 * val (val to be inserted: 0 - 0xf)
207 * Return: void
208 */
209 void
l_setDataQbit(void * line,l_int32 n,l_int32 val)210 l_setDataQbit(void *line,
211 l_int32 n,
212 l_int32 val)
213 {
214 l_uint32 *pword;
215
216 pword = (l_uint32 *)line + (n >> 3);
217 *pword &= ~(0xf0000000 >> (4 * (n & 7))); /* clear */
218 *pword |= val << (28 - 4 * (n & 7)); /* set */
219 return;
220 }
221
222
223 /*!
224 * l_clearDataQbit()
225 *
226 * Input: line (ptr to beginning of data line)
227 * n (pixel index)
228 * Return: void
229 *
230 * Action: sets the (4-bit) pixel to 0
231 */
232 void
l_clearDataQbit(void * line,l_int32 n)233 l_clearDataQbit(void *line,
234 l_int32 n)
235 {
236 *((l_uint32 *)line + (n >> 3)) &= ~(0xf0000000 >> (4 * (n & 7)));
237 }
238
239
240 /*!
241 * l_getDataByte()
242 *
243 * Input: line (ptr to beginning of data line)
244 * n (pixel index)
245 * Return: value of the n-th (byte) pixel
246 */
247 l_int32
l_getDataByte(void * line,l_int32 n)248 l_getDataByte(void *line,
249 l_int32 n)
250 {
251 #ifdef L_BIG_ENDIAN
252 return *((l_uint8 *)line + n);
253 #else /* L_LITTLE_ENDIAN */
254 return *(l_uint8 *)((l_uintptr_t)((l_uint8 *)line + n) ^ 3);
255 #endif /* L_BIG_ENDIAN */
256 }
257
258
259 /*!
260 * l_setDataByte()
261 *
262 * Input: line (ptr to beginning of data line)
263 * n (pixel index)
264 * val (val to be inserted: 0 - 0xff)
265 * Return: void
266 */
267 void
l_setDataByte(void * line,l_int32 n,l_int32 val)268 l_setDataByte(void *line,
269 l_int32 n,
270 l_int32 val)
271 {
272 #ifdef L_BIG_ENDIAN
273 *((l_uint8 *)line + n) = val;
274 #else /* L_LITTLE_ENDIAN */
275 *(l_uint8 *)((l_uintptr_t)((l_uint8 *)line + n) ^ 3) = val;
276 #endif /* L_BIG_ENDIAN */
277 }
278
279
280 /*!
281 * l_getDataTwoBytes()
282 *
283 * Input: line (ptr to beginning of data line)
284 * n (pixel index)
285 * Return: value of the n-th (2-byte) pixel
286 */
287 l_int32
l_getDataTwoBytes(void * line,l_int32 n)288 l_getDataTwoBytes(void *line,
289 l_int32 n)
290 {
291 #ifdef L_BIG_ENDIAN
292 return *((l_uint16 *)line + n);
293 #else /* L_LITTLE_ENDIAN */
294 return *(l_uint16 *)((l_uintptr_t)((l_uint16 *)line + n) ^ 2);
295 #endif /* L_BIG_ENDIAN */
296 }
297
298
299 /*!
300 * l_setDataTwoBytes()
301 *
302 * Input: line (ptr to beginning of data line)
303 * n (pixel index)
304 * val (val to be inserted: 0 - 0xffff)
305 * Return: void
306 */
307 void
l_setDataTwoBytes(void * line,l_int32 n,l_int32 val)308 l_setDataTwoBytes(void *line,
309 l_int32 n,
310 l_int32 val)
311 {
312 #ifdef L_BIG_ENDIAN
313 *((l_uint16 *)line + n) = val;
314 #else /* L_LITTLE_ENDIAN */
315 *(l_uint16 *)((l_uintptr_t)((l_uint16 *)line + n) ^ 2) = val;
316 #endif /* L_BIG_ENDIAN */
317 }
318
319
320 /*!
321 * l_getDataFourBytes()
322 *
323 * Input: line (ptr to beginning of data line)
324 * n (pixel index)
325 * Return: value of the n-th (4-byte) pixel
326 */
327 l_int32
l_getDataFourBytes(void * line,l_int32 n)328 l_getDataFourBytes(void *line,
329 l_int32 n)
330 {
331 return *((l_uint32 *)line + n);
332 }
333
334
335 /*!
336 * l_setDataFourBytes()
337 *
338 * Input: line (ptr to beginning of data line)
339 * n (pixel index)
340 * val (val to be inserted: 0 - 0xffffffff)
341 * Return: void
342 */
343 void
l_setDataFourBytes(void * line,l_int32 n,l_int32 val)344 l_setDataFourBytes(void *line,
345 l_int32 n,
346 l_int32 val)
347 {
348 *((l_uint32 *)line + n) = val;
349 }
350
351
352
353