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  *     #define  SET_DATA_QBIT(pdata, n, val) \
66  *        {l_uint32 *_TEMP_WORD_PTR_; \
67  *         _TEMP_WORD_PTR_ = (l_uint32 *)(pdata) + ((n) >> 3); \
68  *         *_TEMP_WORD_PTR_ &= ~(0xf0000000 >> (4 * ((n) & 7))); \
69  *         *_TEMP_WORD_PTR_ |= (((val) & 15) << (28 - 4 * ((n) & 7)));}
70  *  but if used in an if/else
71  *      if (x)
72  *         SET_DATA_QBIT(...);
73  *      else
74  *         ...
75  *  the compiler sees
76  *      if (x)
77  *         {......};
78  *      else
79  *         ...
80  *  The semicolon comes after the brace and will not compile.
81  *  This can be fixed in the call by either omitting the semicolon
82  *  or requiring another set of braces around SET_DATA_QBIT(), but
83  *  both these options break compatibility with current code, and
84  *  require special attention by anyone using the macros.
85  *
86  *  There are (at least) two ways to fix this in the macro definitions,
87  *  suggested by Dave Bryan.
88  *  (1) Surround the braces in the macro above with
89  *         do {....} while(0)
90  *      Then the semicolon just terminates the expression.
91  *  (2) Reduce the blocks to a single expression; e.g,
92  *         *((l_uint32 *)(pdata) + ((n) >> 3)) = \
93  *           *((l_uint32 *)(pdata) + ((n) >> 3)) \
94  *           & ~(0xf0000000 >> (4 * ((n) & 7))) \
95  *           | (((val) & 15) << (28 - 4 * ((n) & 7)))
96  *      This appears to cause redundant computation, but the compiler
97  *      should evaluate the common subexpression only once.
98  *  All these methods have the same performance, giving about 300M
99  *  SET_DATA_QBIT operations per second on a fast 64 bit system.
100  *  Using the function calls instead of the macros results in about 250M
101  *  SET_DATA_QBIT operations per second, a performance hit of nearly 20%.
102  * </pre>
103  */
104 
105 #define  USE_INLINE_ACCESSORS    1
106 
107 #if USE_INLINE_ACCESSORS
108 
109     /*=============================================================*/
110     /*                Faster: use in line accessors                */
111     /*=============================================================*/
112 
113     /*--------------------------------------------------*
114      *                     1 bit access                 *
115      *--------------------------------------------------*/
116 /*! 1 bit access - get */
117 #define  GET_DATA_BIT(pdata, n) \
118     ((*((l_uint32 *)(pdata) + ((n) >> 5)) >> (31 - ((n) & 31))) & 1)
119 
120 /*! 1 bit access - set */
121 #define  SET_DATA_BIT(pdata, n) \
122     *((l_uint32 *)(pdata) + ((n) >> 5)) |= (0x80000000 >> ((n) & 31))
123 
124 /*! 1 bit access - clear */
125 #define  CLEAR_DATA_BIT(pdata, n) \
126     *((l_uint32 *)(pdata) + ((n) >> 5)) &= ~(0x80000000 >> ((n) & 31))
127 
128 /*! 1 bit access - set value (0 or 1) */
129 #define  SET_DATA_BIT_VAL(pdata, n, val) \
130      *((l_uint32 *)(pdata) + ((n) >> 5)) = \
131         ((*((l_uint32 *)(pdata) + ((n) >> 5)) \
132         & (~(0x80000000 >> ((n) & 31)))) \
133         | ((val) << (31 - ((n) & 31))))
134 
135     /*--------------------------------------------------*
136      *                     2 bit access                 *
137      *--------------------------------------------------*/
138 /*! 2 bit access - get */
139 #define  GET_DATA_DIBIT(pdata, n) \
140     ((*((l_uint32 *)(pdata) + ((n) >> 4)) >> (2 * (15 - ((n) & 15)))) & 3)
141 
142 /*! 2 bit access - set value (0 ... 3) */
143 #define  SET_DATA_DIBIT(pdata, n, val) \
144      *((l_uint32 *)(pdata) + ((n) >> 4)) = \
145         ((*((l_uint32 *)(pdata) + ((n) >> 4)) \
146         & (~(0xc0000000 >> (2 * ((n) & 15))))) \
147         | (((val) & 3) << (30 - 2 * ((n) & 15))))
148 
149 /*! 2 bit access - clear */
150 #define  CLEAR_DATA_DIBIT(pdata, n) \
151     *((l_uint32 *)(pdata) + ((n) >> 4)) &= ~(0xc0000000 >> (2 * ((n) & 15)))
152 
153 
154     /*--------------------------------------------------*
155      *                     4 bit access                 *
156      *--------------------------------------------------*/
157 /*! 4 bit access - get */
158 #define  GET_DATA_QBIT(pdata, n) \
159      ((*((l_uint32 *)(pdata) + ((n) >> 3)) >> (4 * (7 - ((n) & 7)))) & 0xf)
160 
161 /*! 4 bit access - set value (0 ... 15) */
162 #define  SET_DATA_QBIT(pdata, n, val) \
163      *((l_uint32 *)(pdata) + ((n) >> 3)) = \
164         ((*((l_uint32 *)(pdata) + ((n) >> 3)) \
165         & (~(0xf0000000 >> (4 * ((n) & 7))))) \
166         | (((val) & 15) << (28 - 4 * ((n) & 7))))
167 
168 /*! 4 bit access - clear */
169 #define  CLEAR_DATA_QBIT(pdata, n) \
170     *((l_uint32 *)(pdata) + ((n) >> 3)) &= ~(0xf0000000 >> (4 * ((n) & 7)))
171 
172 
173     /*--------------------------------------------------*
174      *                     8 bit access                 *
175      *--------------------------------------------------*/
176 #ifdef  L_BIG_ENDIAN
177 /*! 8 bit access - get */
178 #define  GET_DATA_BYTE(pdata, n) \
179              (*((l_uint8 *)(pdata) + (n)))
180 #else  /* L_LITTLE_ENDIAN */
181 /*! 8 bit access - get */
182 #define  GET_DATA_BYTE(pdata, n) \
183              (*(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3))
184 #endif  /* L_BIG_ENDIAN */
185 
186 #ifdef  L_BIG_ENDIAN
187 /*! 8 bit access - set value (0 ... 255) */
188 #define  SET_DATA_BYTE(pdata, n, val) \
189              *((l_uint8 *)(pdata) + (n)) = (val)
190 #else  /* L_LITTLE_ENDIAN */
191 /*! 8 bit access - set value (0 ... 255) */
192 #define  SET_DATA_BYTE(pdata, n, val) \
193              *(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3) = (val)
194 #endif  /* L_BIG_ENDIAN */
195 
196 
197     /*--------------------------------------------------*
198      *                    16 bit access                 *
199      *--------------------------------------------------*/
200 #ifdef  L_BIG_ENDIAN
201 /*! 16 bit access - get */
202 #define  GET_DATA_TWO_BYTES(pdata, n) \
203              (*((l_uint16 *)(pdata) + (n)))
204 #else  /* L_LITTLE_ENDIAN */
205 /*! 16 bit access - get */
206 #define  GET_DATA_TWO_BYTES(pdata, n) \
207              (*(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2))
208 #endif  /* L_BIG_ENDIAN */
209 
210 #ifdef  L_BIG_ENDIAN
211 /*! 16 bit access - set value (0 ... 65535) */
212 #define  SET_DATA_TWO_BYTES(pdata, n, val) \
213              *((l_uint16 *)(pdata) + (n)) = (val)
214 #else  /* L_LITTLE_ENDIAN */
215 /*! 16 bit access - set value (0 ... 65535) */
216 #define  SET_DATA_TWO_BYTES(pdata, n, val) \
217              *(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2) = (val)
218 #endif  /* L_BIG_ENDIAN */
219 
220 
221     /*--------------------------------------------------*
222      *                    32 bit access                 *
223      *--------------------------------------------------*/
224 /*! 32 bit access - get */
225 #define  GET_DATA_FOUR_BYTES(pdata, n) \
226              (*((l_uint32 *)(pdata) + (n)))
227 
228 /*! 32 bit access - set (0 ... 4294967295) */
229 #define  SET_DATA_FOUR_BYTES(pdata, n, val) \
230              *((l_uint32 *)(pdata) + (n)) = (val)
231 
232 
233 #else
234 
235     /*=============================================================*/
236     /*         Slower: use function calls for all accessors        */
237     /*=============================================================*/
238 
239 #define  GET_DATA_BIT(pdata, n)               l_getDataBit(pdata, n)
240 #define  SET_DATA_BIT(pdata, n)               l_setDataBit(pdata, n)
241 #define  CLEAR_DATA_BIT(pdata, n)             l_clearDataBit(pdata, n)
242 #define  SET_DATA_BIT_VAL(pdata, n, val)      l_setDataBitVal(pdata, n, val)
243 
244 #define  GET_DATA_DIBIT(pdata, n)             l_getDataDibit(pdata, n)
245 #define  SET_DATA_DIBIT(pdata, n, val)        l_setDataDibit(pdata, n, val)
246 #define  CLEAR_DATA_DIBIT(pdata, n)           l_clearDataDibit(pdata, n)
247 
248 #define  GET_DATA_QBIT(pdata, n)              l_getDataQbit(pdata, n)
249 #define  SET_DATA_QBIT(pdata, n, val)         l_setDataQbit(pdata, n, val)
250 #define  CLEAR_DATA_QBIT(pdata, n)            l_clearDataQbit(pdata, n)
251 
252 #define  GET_DATA_BYTE(pdata, n)              l_getDataByte(pdata, n)
253 #define  SET_DATA_BYTE(pdata, n, val)         l_setDataByte(pdata, n, val)
254 
255 #define  GET_DATA_TWO_BYTES(pdata, n)         l_getDataTwoBytes(pdata, n)
256 #define  SET_DATA_TWO_BYTES(pdata, n, val)    l_setDataTwoBytes(pdata, n, val)
257 
258 #define  GET_DATA_FOUR_BYTES(pdata, n)         l_getDataFourBytes(pdata, n)
259 #define  SET_DATA_FOUR_BYTES(pdata, n, val)    l_setDataFourBytes(pdata, n, val)
260 
261 #endif  /* USE_INLINE_ACCESSORS */
262 
263 
264 #endif /* LEPTONICA_ARRAY_ACCESS_H */
265