• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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