arrayaccess.h 11 KB

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