/src/leptonica/src/arrayaccess.c
Line | Count | Source (jump to first uncovered line) |
1 | | /*====================================================================* |
2 | | - Copyright (C) 2001 Leptonica. All rights reserved. |
3 | | - |
4 | | - Redistribution and use in source and binary forms, with or without |
5 | | - modification, are permitted provided that the following conditions |
6 | | - are met: |
7 | | - 1. Redistributions of source code must retain the above copyright |
8 | | - notice, this list of conditions and the following disclaimer. |
9 | | - 2. Redistributions in binary form must reproduce the above |
10 | | - copyright notice, this list of conditions and the following |
11 | | - disclaimer in the documentation and/or other materials |
12 | | - provided with the distribution. |
13 | | - |
14 | | - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
15 | | - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
16 | | - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
17 | | - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY |
18 | | - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | | - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 | | - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 | | - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 | | - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
23 | | - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
24 | | - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | | *====================================================================*/ |
26 | | |
27 | | /*! |
28 | | * \file arrayaccess.c |
29 | | * <pre> |
30 | | * |
31 | | * Access within an array of 32-bit words |
32 | | * |
33 | | * l_int32 l_getDataBit() |
34 | | * void l_setDataBit() |
35 | | * void l_clearDataBit() |
36 | | * void l_setDataBitVal() |
37 | | * l_int32 l_getDataDibit() |
38 | | * void l_setDataDibit() |
39 | | * void l_clearDataDibit() |
40 | | * l_int32 l_getDataQbit() |
41 | | * void l_setDataQbit() |
42 | | * void l_clearDataQbit() |
43 | | * l_int32 l_getDataByte() |
44 | | * void l_setDataByte() |
45 | | * l_int32 l_getDataTwoBytes() |
46 | | * void l_setDataTwoBytes() |
47 | | * l_int32 l_getDataFourBytes() |
48 | | * void l_setDataFourBytes() |
49 | | * |
50 | | * Note that these all require 32-bit alignment, and hence an input |
51 | | * ptr to l_uint32. However, this is not enforced by the compiler. |
52 | | * Instead, we allow the use of a void* ptr, because the line ptrs |
53 | | * are an efficient way to get random access (see pixGetLinePtrs()). |
54 | | * It is then necessary to cast internally within each function |
55 | | * because ptr arithmetic requires knowing the size of the units |
56 | | * being referenced. |
57 | | * </pre> |
58 | | */ |
59 | | |
60 | | #ifdef HAVE_CONFIG_H |
61 | | #include <config_auto.h> |
62 | | #endif /* HAVE_CONFIG_H */ |
63 | | |
64 | | #include "allheaders.h" |
65 | | |
66 | | /*----------------------------------------------------------------------* |
67 | | * Access within an array of 32-bit words * |
68 | | *----------------------------------------------------------------------*/ |
69 | | /*! |
70 | | * \brief l_getDataBit() |
71 | | * |
72 | | * \param[in] line ptr to beginning of data line |
73 | | * \param[in] n pixel index |
74 | | * \return val of the nth 1-bit pixel. |
75 | | */ |
76 | | l_int32 |
77 | | l_getDataBit(const void *line, |
78 | | l_int32 n) |
79 | 0 | { |
80 | 0 | return (*((const l_uint32 *)line + (n >> 5)) >> (31 - (n & 31))) & 1; |
81 | 0 | } |
82 | | |
83 | | |
84 | | /*! |
85 | | * \brief l_setDataBit() |
86 | | * |
87 | | * \param[in] line ptr to beginning of data line |
88 | | * \param[in] n pixel index |
89 | | * \return void |
90 | | * |
91 | | * Action: sets the pixel to 1 |
92 | | */ |
93 | | void |
94 | | l_setDataBit(void *line, |
95 | | l_int32 n) |
96 | 0 | { |
97 | 0 | *((l_uint32 *)line + (n >> 5)) |= (0x80000000 >> (n & 31)); |
98 | 0 | } |
99 | | |
100 | | |
101 | | /*! |
102 | | * \brief l_clearDataBit() |
103 | | * |
104 | | * \param[in] line ptr to beginning of data line |
105 | | * \param[in] n pixel index |
106 | | * \return void |
107 | | * |
108 | | * Action: sets the 1-bit pixel to 0 |
109 | | */ |
110 | | void |
111 | | l_clearDataBit(void *line, |
112 | | l_int32 n) |
113 | 0 | { |
114 | 0 | *((l_uint32 *)line + (n >> 5)) &= ~(0x80000000 >> (n & 31)); |
115 | 0 | } |
116 | | |
117 | | |
118 | | /*! |
119 | | * \brief l_setDataBitVal() |
120 | | * |
121 | | * \param[in] line ptr to beginning of data line |
122 | | * \param[in] n pixel index |
123 | | * \param[in] val val to be inserted: 0 or 1 |
124 | | * \return void |
125 | | * |
126 | | * <pre> |
127 | | * Notes: |
128 | | * (1) This is an accessor for a 1 bpp pix. |
129 | | * (2) It is actually a little slower than using: |
130 | | * if (val == 0) |
131 | | * l_ClearDataBit(line, n); |
132 | | * else |
133 | | * l_SetDataBit(line, n); |
134 | | * </pre> |
135 | | */ |
136 | | void |
137 | | l_setDataBitVal(void *line, |
138 | | l_int32 n, |
139 | | l_int32 val) |
140 | 0 | { |
141 | 0 | l_uint32 *pword; |
142 | |
|
143 | 0 | pword = (l_uint32 *)line + (n >> 5); |
144 | 0 | *pword &= ~(0x80000000 >> (n & 31)); /* clear */ |
145 | 0 | *pword |= (l_uint32)val << (31 - (n & 31)); /* set */ |
146 | 0 | } |
147 | | |
148 | | |
149 | | /*! |
150 | | * \brief l_getDataDibit() |
151 | | * |
152 | | * \param[in] line ptr to beginning of data line |
153 | | * \param[in] n pixel index |
154 | | * \return val of the nth 2-bit pixel. |
155 | | */ |
156 | | l_int32 |
157 | | l_getDataDibit(const void *line, |
158 | | l_int32 n) |
159 | 0 | { |
160 | 0 | return (*((const l_uint32 *)line + (n >> 4)) >> (2 * (15 - (n & 15)))) & 3; |
161 | 0 | } |
162 | | |
163 | | |
164 | | /*! |
165 | | * \brief l_setDataDibit() |
166 | | * |
167 | | * \param[in] line ptr to beginning of data line |
168 | | * \param[in] n pixel index |
169 | | * \param[in] val val to be inserted: 0 - 3 |
170 | | * \return void |
171 | | */ |
172 | | void |
173 | | l_setDataDibit(void *line, |
174 | | l_int32 n, |
175 | | l_int32 val) |
176 | 0 | { |
177 | 0 | l_uint32 *pword; |
178 | |
|
179 | 0 | pword = (l_uint32 *)line + (n >> 4); |
180 | 0 | *pword &= ~(0xc0000000 >> (2 * (n & 15))); /* clear */ |
181 | 0 | *pword |= (l_uint32)(val & 3) << (30 - 2 * (n & 15)); /* set */ |
182 | 0 | } |
183 | | |
184 | | |
185 | | /*! |
186 | | * \brief l_clearDataDibit() |
187 | | * |
188 | | * \param[in] line ptr to beginning of data line |
189 | | * \param[in] n pixel index |
190 | | * \return void |
191 | | * |
192 | | * Action: sets the 2-bit pixel to 0 |
193 | | */ |
194 | | void |
195 | | l_clearDataDibit(void *line, |
196 | | l_int32 n) |
197 | 0 | { |
198 | 0 | *((l_uint32 *)line + (n >> 4)) &= ~(0xc0000000 >> (2 * (n & 15))); |
199 | 0 | } |
200 | | |
201 | | |
202 | | /*! |
203 | | * \brief l_getDataQbit() |
204 | | * |
205 | | * \param[in] line ptr to beginning of data line |
206 | | * \param[in] n pixel index |
207 | | * \return val of the nth 4-bit pixel. |
208 | | */ |
209 | | l_int32 |
210 | | l_getDataQbit(const void *line, |
211 | | l_int32 n) |
212 | 0 | { |
213 | 0 | return (*((const l_uint32 *)line + (n >> 3)) >> (4 * (7 - (n & 7)))) & 0xf; |
214 | 0 | } |
215 | | |
216 | | |
217 | | /*! |
218 | | * \brief l_setDataQbit() |
219 | | * |
220 | | * \param[in] line ptr to beginning of data line |
221 | | * \param[in] n pixel index |
222 | | * \param[in] val val to be inserted: 0 - 0xf |
223 | | * \return void |
224 | | */ |
225 | | void |
226 | | l_setDataQbit(void *line, |
227 | | l_int32 n, |
228 | | l_int32 val) |
229 | 0 | { |
230 | 0 | l_uint32 *pword; |
231 | |
|
232 | 0 | pword = (l_uint32 *)line + (n >> 3); |
233 | 0 | *pword &= ~(0xf0000000 >> (4 * (n & 7))); /* clear */ |
234 | 0 | *pword |= (l_uint32)(val & 15) << (28 - 4 * (n & 7)); /* set */ |
235 | 0 | } |
236 | | |
237 | | |
238 | | /*! |
239 | | * \brief l_clearDataQbit() |
240 | | * |
241 | | * \param[in] line ptr to beginning of data line |
242 | | * \param[in] n pixel index |
243 | | * \return void |
244 | | * |
245 | | * Action: sets the 4-bit pixel to 0 |
246 | | */ |
247 | | void |
248 | | l_clearDataQbit(void *line, |
249 | | l_int32 n) |
250 | 0 | { |
251 | 0 | *((l_uint32 *)line + (n >> 3)) &= ~(0xf0000000 >> (4 * (n & 7))); |
252 | 0 | } |
253 | | |
254 | | |
255 | | /*! |
256 | | * \brief l_getDataByte() |
257 | | * |
258 | | * \param[in] line ptr to beginning of data line |
259 | | * \param[in] n pixel index |
260 | | * \return value of the n-th byte pixel |
261 | | */ |
262 | | l_int32 |
263 | | l_getDataByte(const void *line, |
264 | | l_int32 n) |
265 | 0 | { |
266 | | #ifdef L_BIG_ENDIAN |
267 | | return *((const l_uint8 *)line + n); |
268 | | #else /* L_LITTLE_ENDIAN */ |
269 | 0 | return *(l_uint8 *)((l_uintptr_t)((const l_uint8 *)line + n) ^ 3); |
270 | 0 | #endif /* L_BIG_ENDIAN */ |
271 | 0 | } |
272 | | |
273 | | |
274 | | /*! |
275 | | * \brief l_setDataByte() |
276 | | * |
277 | | * \param[in] line ptr to beginning of data line |
278 | | * \param[in] n pixel index |
279 | | * \param[in] val val to be inserted: 0 - 0xff |
280 | | * \return void |
281 | | */ |
282 | | void |
283 | | l_setDataByte(void *line, |
284 | | l_int32 n, |
285 | | l_int32 val) |
286 | 0 | { |
287 | | #ifdef L_BIG_ENDIAN |
288 | | *((l_uint8 *)line + n) = val; |
289 | | #else /* L_LITTLE_ENDIAN */ |
290 | 0 | *(l_uint8 *)((l_uintptr_t)((l_uint8 *)line + n) ^ 3) = val; |
291 | 0 | #endif /* L_BIG_ENDIAN */ |
292 | 0 | } |
293 | | |
294 | | |
295 | | /*! |
296 | | * \brief l_getDataTwoBytes() |
297 | | * |
298 | | * \param[in] line ptr to beginning of data line |
299 | | * \param[in] n pixel index |
300 | | * \return value of the n-th 2-byte pixel |
301 | | */ |
302 | | l_int32 |
303 | | l_getDataTwoBytes(const void *line, |
304 | | l_int32 n) |
305 | 0 | { |
306 | | #ifdef L_BIG_ENDIAN |
307 | | return *((const l_uint16 *)line + n); |
308 | | #else /* L_LITTLE_ENDIAN */ |
309 | 0 | return *(l_uint16 *)((l_uintptr_t)((const l_uint16 *)line + n) ^ 2); |
310 | 0 | #endif /* L_BIG_ENDIAN */ |
311 | 0 | } |
312 | | |
313 | | |
314 | | /*! |
315 | | * \brief l_setDataTwoBytes() |
316 | | * |
317 | | * \param[in] line ptr to beginning of data line |
318 | | * \param[in] n pixel index |
319 | | * \param[in] val val to be inserted: 0 - 0xffff |
320 | | * \return void |
321 | | */ |
322 | | void |
323 | | l_setDataTwoBytes(void *line, |
324 | | l_int32 n, |
325 | | l_int32 val) |
326 | 0 | { |
327 | | #ifdef L_BIG_ENDIAN |
328 | | *((l_uint16 *)line + n) = val; |
329 | | #else /* L_LITTLE_ENDIAN */ |
330 | 0 | *(l_uint16 *)((l_uintptr_t)((l_uint16 *)line + n) ^ 2) = val; |
331 | 0 | #endif /* L_BIG_ENDIAN */ |
332 | 0 | } |
333 | | |
334 | | |
335 | | /*! |
336 | | * \brief l_getDataFourBytes() |
337 | | * |
338 | | * \param[in] line ptr to beginning of data line |
339 | | * \param[in] n pixel index |
340 | | * \return value of the n-th 4-byte pixel |
341 | | */ |
342 | | l_int32 |
343 | | l_getDataFourBytes(const void *line, |
344 | | l_int32 n) |
345 | 0 | { |
346 | 0 | return *((const l_uint32 *)line + n); |
347 | 0 | } |
348 | | |
349 | | |
350 | | /*! |
351 | | * \brief l_setDataFourBytes() |
352 | | * |
353 | | * \param[in] line ptr to beginning of data line |
354 | | * \param[in] n pixel index |
355 | | * \param[in] val val to be inserted: 0 - 0xffffffff |
356 | | * \return void |
357 | | */ |
358 | | void |
359 | | l_setDataFourBytes(void *line, |
360 | | l_int32 n, |
361 | | l_int32 val) |
362 | 0 | { |
363 | 0 | *((l_uint32 *)line + n) = val; |
364 | 0 | } |