comparison mupdf-source/thirdparty/leptonica/src/arrayaccess.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
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 {
80 return (*((const l_uint32 *)line + (n >> 5)) >> (31 - (n & 31))) & 1;
81 }
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 {
97 *((l_uint32 *)line + (n >> 5)) |= (0x80000000 >> (n & 31));
98 }
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 {
114 *((l_uint32 *)line + (n >> 5)) &= ~(0x80000000 >> (n & 31));
115 }
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 {
141 l_uint32 *pword;
142
143 pword = (l_uint32 *)line + (n >> 5);
144 *pword &= ~(0x80000000 >> (n & 31)); /* clear */
145 *pword |= (l_uint32)val << (31 - (n & 31)); /* set */
146 }
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 {
160 return (*((const l_uint32 *)line + (n >> 4)) >> (2 * (15 - (n & 15)))) & 3;
161 }
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 {
177 l_uint32 *pword;
178
179 pword = (l_uint32 *)line + (n >> 4);
180 *pword &= ~(0xc0000000 >> (2 * (n & 15))); /* clear */
181 *pword |= (l_uint32)(val & 3) << (30 - 2 * (n & 15)); /* set */
182 }
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 {
198 *((l_uint32 *)line + (n >> 4)) &= ~(0xc0000000 >> (2 * (n & 15)));
199 }
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 {
213 return (*((const l_uint32 *)line + (n >> 3)) >> (4 * (7 - (n & 7)))) & 0xf;
214 }
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 {
230 l_uint32 *pword;
231
232 pword = (l_uint32 *)line + (n >> 3);
233 *pword &= ~(0xf0000000 >> (4 * (n & 7))); /* clear */
234 *pword |= (l_uint32)(val & 15) << (28 - 4 * (n & 7)); /* set */
235 }
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 {
251 *((l_uint32 *)line + (n >> 3)) &= ~(0xf0000000 >> (4 * (n & 7)));
252 }
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 {
266 #ifdef L_BIG_ENDIAN
267 return *((const l_uint8 *)line + n);
268 #else /* L_LITTLE_ENDIAN */
269 return *(l_uint8 *)((l_uintptr_t)((const l_uint8 *)line + n) ^ 3);
270 #endif /* L_BIG_ENDIAN */
271 }
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 {
287 #ifdef L_BIG_ENDIAN
288 *((l_uint8 *)line + n) = val;
289 #else /* L_LITTLE_ENDIAN */
290 *(l_uint8 *)((l_uintptr_t)((l_uint8 *)line + n) ^ 3) = val;
291 #endif /* L_BIG_ENDIAN */
292 }
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 {
306 #ifdef L_BIG_ENDIAN
307 return *((const l_uint16 *)line + n);
308 #else /* L_LITTLE_ENDIAN */
309 return *(l_uint16 *)((l_uintptr_t)((const l_uint16 *)line + n) ^ 2);
310 #endif /* L_BIG_ENDIAN */
311 }
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 {
327 #ifdef L_BIG_ENDIAN
328 *((l_uint16 *)line + n) = val;
329 #else /* L_LITTLE_ENDIAN */
330 *(l_uint16 *)((l_uintptr_t)((l_uint16 *)line + n) ^ 2) = val;
331 #endif /* L_BIG_ENDIAN */
332 }
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 {
346 return *((const l_uint32 *)line + n);
347 }
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 {
363 *((l_uint32 *)line + n) = val;
364 }