Coverage Report

Created: 2025-06-13 06:49

/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
}