comparison mupdf-source/thirdparty/leptonica/src/arrayaccess.h @ 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 #ifndef LEPTONICA_ARRAY_ACCESS_H
28 #define LEPTONICA_ARRAY_ACCESS_H
29
30 /*!
31 * \file arrayaccess.h
32 *
33 * <pre>
34 * 1, 2, 4, 8, 16 and 32 bit data access within an array of 32-bit words
35 *
36 * This is used primarily to access 1, 2, 4, 8, 16 and 32 bit pixels
37 * in a line of image data, represented as an array of 32-bit words.
38 *
39 * pdata: pointer to first 32-bit word in the array
40 * n: index of the pixel in the array
41 *
42 * Function calls for these accessors are defined in arrayaccess.c.
43 *
44 * However, for efficiency we use the inline macros for all accesses.
45 * Even though the 2 and 4 bit set* accessors are more complicated,
46 * they are about 10% faster than the function calls.
47 *
48 * The 32 bit access is just a cast and ptr arithmetic. We include
49 * it so that the input ptr can be void*.
50 *
51 * At the end of this file is code for invoking the function calls
52 * instead of inlining.
53 *
54 * The macro SET_DATA_BIT_VAL(pdata, n, val) is a bit slower than
55 * if (val == 0)
56 * CLEAR_DATA_BIT(pdata, n);
57 * else
58 * SET_DATA_BIT(pdata, n);
59 *
60 * Some compilers complain when the SET macros are surrounded by
61 * parentheses, because parens require an evaluation and it is not
62 * defined for SET macros. If SET_DATA_QBIT were defined as a
63 * compound macro, in analogy to l_setDataQbit(), it requires
64 * surrounding braces:
65 * \code
66 * #define SET_DATA_QBIT(pdata, n, val) \
67 * {l_uint32 *_TEMP_WORD_PTR_; \
68 * _TEMP_WORD_PTR_ = (l_uint32 *)(pdata) + ((n) >> 3); \
69 * *_TEMP_WORD_PTR_ &= ~(0xf0000000 >> (4 * ((n) & 7))); \
70 * *_TEMP_WORD_PTR_ |= (((val) & 15) << (28 - 4 * ((n) & 7)));}
71 * \endcode
72 * but if used in an if/else
73 * \code
74 * if (x)
75 * SET_DATA_QBIT(...);
76 * else
77 * ...
78 * \endcode
79 * the compiler sees
80 * \code
81 * if (x)
82 * {......};
83 * else
84 * ...
85 * \endcode
86 * The semicolon comes after the brace and will not compile.
87 * This can be fixed in the call by either omitting the semicolon
88 * or requiring another set of braces around SET_DATA_QBIT(), but
89 * both these options break compatibility with current code, and
90 * require special attention by anyone using the macros.
91 *
92 * There are (at least) two ways to fix this in the macro definitions,
93 * suggested by Dave Bryan.
94 * (1) Surround the braces in the macro above with
95 * do {....} while(0)
96 * Then the semicolon just terminates the expression.
97 * (2) Reduce the blocks to a single expression; e.g,
98 * *((l_uint32 *)(pdata) + ((n) >> 3)) = \
99 * *((l_uint32 *)(pdata) + ((n) >> 3)) \
100 * & ~(0xf0000000 >> (4 * ((n) & 7))) \
101 * | (((val) & 15) << (28 - 4 * ((n) & 7)))
102 * This appears to cause redundant computation, but the compiler
103 * should evaluate the common subexpression only once.
104 * All these methods have the same performance, giving about 300M
105 * SET_DATA_QBIT operations per second on a fast 64 bit system.
106 * Using the function calls instead of the macros results in about 250M
107 * SET_DATA_QBIT operations per second, a performance hit of nearly 20%.
108 * </pre>
109 */
110
111 #define USE_INLINE_ACCESSORS 1
112
113 #if USE_INLINE_ACCESSORS
114
115 /*=============================================================*/
116 /* Faster: use in line accessors */
117 /*=============================================================*/
118
119 /*--------------------------------------------------*
120 * 1 bit access *
121 *--------------------------------------------------*/
122 /*! 1 bit access - get */
123 #define GET_DATA_BIT(pdata, n) \
124 ((*((const l_uint32 *)(pdata) + ((n) >> 5)) >> (31 - ((n) & 31))) & 1)
125
126 /*! 1 bit access - set */
127 #define SET_DATA_BIT(pdata, n) \
128 *((l_uint32 *)(pdata) + ((n) >> 5)) |= (0x80000000 >> ((n) & 31))
129
130 /*! 1 bit access - clear */
131 #define CLEAR_DATA_BIT(pdata, n) \
132 *((l_uint32 *)(pdata) + ((n) >> 5)) &= ~(0x80000000 >> ((n) & 31))
133
134 /*! 1 bit access - set value (0 or 1) */
135 #define SET_DATA_BIT_VAL(pdata, n, val) \
136 *((l_uint32 *)(pdata) + ((n) >> 5)) = \
137 ((*((l_uint32 *)(pdata) + ((n) >> 5)) \
138 & (~(0x80000000 >> ((n) & 31)))) \
139 | ((l_uint32)(val) << (31 - ((n) & 31))))
140
141 /*--------------------------------------------------*
142 * 2 bit access *
143 *--------------------------------------------------*/
144 /*! 2 bit access - get */
145 #define GET_DATA_DIBIT(pdata, n) \
146 ((*((const l_uint32 *)(pdata) + ((n) >> 4)) >> (2 * (15 - ((n) & 15)))) & 3)
147
148 /*! 2 bit access - set value (0 ... 3) */
149 #define SET_DATA_DIBIT(pdata, n, val) \
150 *((l_uint32 *)(pdata) + ((n) >> 4)) = \
151 ((*((l_uint32 *)(pdata) + ((n) >> 4)) \
152 & (~(0xc0000000 >> (2 * ((n) & 15))))) \
153 | ((l_uint32)((val) & 3) << (30 - 2 * ((n) & 15))))
154
155 /*! 2 bit access - clear */
156 #define CLEAR_DATA_DIBIT(pdata, n) \
157 *((l_uint32 *)(pdata) + ((n) >> 4)) &= ~(0xc0000000 >> (2 * ((n) & 15)))
158
159
160 /*--------------------------------------------------*
161 * 4 bit access *
162 *--------------------------------------------------*/
163 /*! 4 bit access - get */
164 #define GET_DATA_QBIT(pdata, n) \
165 ((*((const l_uint32 *)(pdata) + ((n) >> 3)) >> (4 * (7 - ((n) & 7)))) & 0xf)
166
167 /*! 4 bit access - set value (0 ... 15) */
168 #define SET_DATA_QBIT(pdata, n, val) \
169 *((l_uint32 *)(pdata) + ((n) >> 3)) = \
170 ((*((l_uint32 *)(pdata) + ((n) >> 3)) \
171 & (~(0xf0000000 >> (4 * ((n) & 7))))) \
172 | ((l_uint32)((val) & 15) << (28 - 4 * ((n) & 7))))
173
174 /*! 4 bit access - clear */
175 #define CLEAR_DATA_QBIT(pdata, n) \
176 *((l_uint32 *)(pdata) + ((n) >> 3)) &= ~(0xf0000000 >> (4 * ((n) & 7)))
177
178
179 /*--------------------------------------------------*
180 * 8 bit access *
181 *--------------------------------------------------*/
182 #ifdef L_BIG_ENDIAN
183 /*! 8 bit access - get */
184 #define GET_DATA_BYTE(pdata, n) \
185 (*((const l_uint8 *)(pdata) + (n)))
186 #else /* L_LITTLE_ENDIAN */
187 /*! 8 bit access - get */
188 #define GET_DATA_BYTE(pdata, n) \
189 (*(l_uint8 *)((l_uintptr_t)((const l_uint8 *)(pdata) + (n)) ^ 3))
190 #endif /* L_BIG_ENDIAN */
191
192 #ifdef L_BIG_ENDIAN
193 /*! 8 bit access - set value (0 ... 255) */
194 #define SET_DATA_BYTE(pdata, n, val) \
195 *((l_uint8 *)(pdata) + (n)) = (val)
196 #else /* L_LITTLE_ENDIAN */
197 /*! 8 bit access - set value (0 ... 255) */
198 #define SET_DATA_BYTE(pdata, n, val) \
199 *(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3) = (val)
200 #endif /* L_BIG_ENDIAN */
201
202
203 /*--------------------------------------------------*
204 * 16 bit access *
205 *--------------------------------------------------*/
206 #ifdef L_BIG_ENDIAN
207 /*! 16 bit access - get */
208 #define GET_DATA_TWO_BYTES(pdata, n) \
209 (*((const l_uint16 *)(pdata) + (n)))
210 #else /* L_LITTLE_ENDIAN */
211 /*! 16 bit access - get */
212 #define GET_DATA_TWO_BYTES(pdata, n) \
213 (*(l_uint16 *)((l_uintptr_t)((const l_uint16 *)(pdata) + (n)) ^ 2))
214 #endif /* L_BIG_ENDIAN */
215
216 #ifdef L_BIG_ENDIAN
217 /*! 16 bit access - set value (0 ... 65535) */
218 #define SET_DATA_TWO_BYTES(pdata, n, val) \
219 *((l_uint16 *)(pdata) + (n)) = (val)
220 #else /* L_LITTLE_ENDIAN */
221 /*! 16 bit access - set value (0 ... 65535) */
222 #define SET_DATA_TWO_BYTES(pdata, n, val) \
223 *(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2) = (val)
224 #endif /* L_BIG_ENDIAN */
225
226
227 /*--------------------------------------------------*
228 * 32 bit access *
229 *--------------------------------------------------*/
230 /*! 32 bit access - get */
231 #define GET_DATA_FOUR_BYTES(pdata, n) \
232 (*((const l_uint32 *)(pdata) + (n)))
233
234 /*! 32 bit access - set (0 ... 4294967295) */
235 #define SET_DATA_FOUR_BYTES(pdata, n, val) \
236 *((l_uint32 *)(pdata) + (n)) = (val)
237
238
239 #else
240
241 /*=============================================================*/
242 /* Slower: use function calls for all accessors */
243 /*=============================================================*/
244
245 #define GET_DATA_BIT(pdata, n) l_getDataBit(pdata, n)
246 #define SET_DATA_BIT(pdata, n) l_setDataBit(pdata, n)
247 #define CLEAR_DATA_BIT(pdata, n) l_clearDataBit(pdata, n)
248 #define SET_DATA_BIT_VAL(pdata, n, val) l_setDataBitVal(pdata, n, val)
249
250 #define GET_DATA_DIBIT(pdata, n) l_getDataDibit(pdata, n)
251 #define SET_DATA_DIBIT(pdata, n, val) l_setDataDibit(pdata, n, val)
252 #define CLEAR_DATA_DIBIT(pdata, n) l_clearDataDibit(pdata, n)
253
254 #define GET_DATA_QBIT(pdata, n) l_getDataQbit(pdata, n)
255 #define SET_DATA_QBIT(pdata, n, val) l_setDataQbit(pdata, n, val)
256 #define CLEAR_DATA_QBIT(pdata, n) l_clearDataQbit(pdata, n)
257
258 #define GET_DATA_BYTE(pdata, n) l_getDataByte(pdata, n)
259 #define SET_DATA_BYTE(pdata, n, val) l_setDataByte(pdata, n, val)
260
261 #define GET_DATA_TWO_BYTES(pdata, n) l_getDataTwoBytes(pdata, n)
262 #define SET_DATA_TWO_BYTES(pdata, n, val) l_setDataTwoBytes(pdata, n, val)
263
264 #define GET_DATA_FOUR_BYTES(pdata, n) l_getDataFourBytes(pdata, n)
265 #define SET_DATA_FOUR_BYTES(pdata, n, val) l_setDataFourBytes(pdata, n, val)
266
267 #endif /* USE_INLINE_ACCESSORS */
268
269
270 #endif /* LEPTONICA_ARRAY_ACCESS_H */