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