arrayaccess.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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. * arrayaccess.h
  30. *
  31. * 1, 2, 4, 8, 16 and 32 bit data access within an array of 32-bit words
  32. *
  33. * This is used primarily to access 1, 2, 4, 8, 16 and 32 bit pixels
  34. * in a line of image data, represented as an array of 32-bit words.
  35. *
  36. * pdata: pointer to first 32-bit word in the array
  37. * n: index of the pixel in the array
  38. *
  39. * Function calls for these accessors are defined in arrayaccess.c.
  40. *
  41. * However, for efficiency we use the inline macros for all accesses.
  42. * Even though the 2 and 4 bit set* accessors are more complicated,
  43. * they are about 10% faster than the function calls.
  44. *
  45. * The 32 bit access is just a cast and ptr arithmetic. We include
  46. * it so that the input ptr can be void*.
  47. *
  48. * At the end of this file is code for invoking the function calls
  49. * instead of inlining.
  50. *
  51. * The macro SET_DATA_BIT_VAL(pdata, n, val) is a bit slower than
  52. * if (val == 0)
  53. * CLEAR_DATA_BIT(pdata, n);
  54. * else
  55. * SET_DATA_BIT(pdata, n);
  56. */
  57. /* Use the inline accessors (except with _MSC_VER), because they
  58. * are faster. */
  59. #define USE_INLINE_ACCESSORS 1
  60. #if USE_INLINE_ACCESSORS
  61. #ifndef _MSC_VER
  62. /*--------------------------------------------------*
  63. * 1 bit access *
  64. *--------------------------------------------------*/
  65. #define GET_DATA_BIT(pdata, n) \
  66. ((*((l_uint32 *)(pdata) + ((n) >> 5)) >> (31 - ((n) & 31))) & 1)
  67. #define SET_DATA_BIT(pdata, n) \
  68. (*((l_uint32 *)(pdata) + ((n) >> 5)) |= (0x80000000 >> ((n) & 31)))
  69. #define CLEAR_DATA_BIT(pdata, n) \
  70. (*((l_uint32 *)(pdata) + ((n) >> 5)) &= ~(0x80000000 >> ((n) & 31)))
  71. #define SET_DATA_BIT_VAL(pdata, n, val) \
  72. ({l_uint32 *_TEMP_WORD_PTR_; \
  73. _TEMP_WORD_PTR_ = (l_uint32 *)(pdata) + ((n) >> 5); \
  74. *_TEMP_WORD_PTR_ &= ~(0x80000000 >> ((n) & 31)); \
  75. *_TEMP_WORD_PTR_ |= ((val) << (31 - ((n) & 31))); \
  76. })
  77. /*--------------------------------------------------*
  78. * 2 bit access *
  79. *--------------------------------------------------*/
  80. #define GET_DATA_DIBIT(pdata, n) \
  81. ((*((l_uint32 *)(pdata) + ((n) >> 4)) >> (2 * (15 - ((n) & 15)))) & 3)
  82. #define SET_DATA_DIBIT(pdata, n, val) \
  83. ({l_uint32 *_TEMP_WORD_PTR_; \
  84. _TEMP_WORD_PTR_ = (l_uint32 *)(pdata) + ((n) >> 4); \
  85. *_TEMP_WORD_PTR_ &= ~(0xc0000000 >> (2 * ((n) & 15))); \
  86. *_TEMP_WORD_PTR_ |= (((val) & 3) << (30 - 2 * ((n) & 15))); \
  87. })
  88. #define CLEAR_DATA_DIBIT(pdata, n) \
  89. (*((l_uint32 *)(pdata) + ((n) >> 4)) &= ~(0xc0000000 >> (2 * ((n) & 15))))
  90. /*--------------------------------------------------*
  91. * 4 bit access *
  92. *--------------------------------------------------*/
  93. #define GET_DATA_QBIT(pdata, n) \
  94. ((*((l_uint32 *)(pdata) + ((n) >> 3)) >> (4 * (7 - ((n) & 7)))) & 0xf)
  95. #define SET_DATA_QBIT(pdata, n, val) \
  96. ({l_uint32 *_TEMP_WORD_PTR_; \
  97. _TEMP_WORD_PTR_ = (l_uint32 *)(pdata) + ((n) >> 3); \
  98. *_TEMP_WORD_PTR_ &= ~(0xf0000000 >> (4 * ((n) & 7))); \
  99. *_TEMP_WORD_PTR_ |= (((val) & 15) << (28 - 4 * ((n) & 7))); \
  100. })
  101. #define CLEAR_DATA_QBIT(pdata, n) \
  102. (*((l_uint32 *)(pdata) + ((n) >> 3)) &= ~(0xf0000000 >> (4 * ((n) & 7))))
  103. /*--------------------------------------------------*
  104. * 8 bit access *
  105. *--------------------------------------------------*/
  106. #ifdef L_BIG_ENDIAN
  107. #define GET_DATA_BYTE(pdata, n) \
  108. (*((l_uint8 *)(pdata) + (n)))
  109. #else /* L_LITTLE_ENDIAN */
  110. #define GET_DATA_BYTE(pdata, n) \
  111. (*(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3))
  112. #endif /* L_BIG_ENDIAN */
  113. #ifdef L_BIG_ENDIAN
  114. #define SET_DATA_BYTE(pdata, n, val) \
  115. (*((l_uint8 *)(pdata) + (n)) = (val))
  116. #else /* L_LITTLE_ENDIAN */
  117. #define SET_DATA_BYTE(pdata, n, val) \
  118. (*(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3) = (val))
  119. #endif /* L_BIG_ENDIAN */
  120. /*--------------------------------------------------*
  121. * 16 bit access *
  122. *--------------------------------------------------*/
  123. #ifdef L_BIG_ENDIAN
  124. #define GET_DATA_TWO_BYTES(pdata, n) \
  125. (*((l_uint16 *)(pdata) + (n)))
  126. #else /* L_LITTLE_ENDIAN */
  127. #define GET_DATA_TWO_BYTES(pdata, n) \
  128. (*(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2))
  129. #endif /* L_BIG_ENDIAN */
  130. #ifdef L_BIG_ENDIAN
  131. #define SET_DATA_TWO_BYTES(pdata, n, val) \
  132. (*((l_uint16 *)(pdata) + (n)) = (val))
  133. #else /* L_LITTLE_ENDIAN */
  134. #define SET_DATA_TWO_BYTES(pdata, n, val) \
  135. (*(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2) = (val))
  136. #endif /* L_BIG_ENDIAN */
  137. /*--------------------------------------------------*
  138. * 32 bit access *
  139. *--------------------------------------------------*/
  140. #define GET_DATA_FOUR_BYTES(pdata, n) \
  141. (*((l_uint32 *)(pdata) + (n)))
  142. #define SET_DATA_FOUR_BYTES(pdata, n, val) \
  143. (*((l_uint32 *)(pdata) + (n)) = (val))
  144. #endif /* ! _MSC_VER */
  145. #endif /* USE_INLINE_ACCESSORS */
  146. /*--------------------------------------------------*
  147. * Slower, using function calls for all accessors *
  148. *--------------------------------------------------*/
  149. #if !USE_INLINE_ACCESSORS || defined(_MSC_VER)
  150. #define GET_DATA_BIT(pdata, n) l_getDataBit(pdata, n)
  151. #define SET_DATA_BIT(pdata, n) l_setDataBit(pdata, n)
  152. #define CLEAR_DATA_BIT(pdata, n) l_clearDataBit(pdata, n)
  153. #define SET_DATA_BIT_VAL(pdata, n, val) l_setDataBitVal(pdata, n, val)
  154. #define GET_DATA_DIBIT(pdata, n) l_getDataDibit(pdata, n)
  155. #define SET_DATA_DIBIT(pdata, n, val) l_setDataDibit(pdata, n, val)
  156. #define CLEAR_DATA_DIBIT(pdata, n) l_clearDataDibit(pdata, n)
  157. #define GET_DATA_QBIT(pdata, n) l_getDataQbit(pdata, n)
  158. #define SET_DATA_QBIT(pdata, n, val) l_setDataQbit(pdata, n, val)
  159. #define CLEAR_DATA_QBIT(pdata, n) l_clearDataQbit(pdata, n)
  160. #define GET_DATA_BYTE(pdata, n) l_getDataByte(pdata, n)
  161. #define SET_DATA_BYTE(pdata, n, val) l_setDataByte(pdata, n, val)
  162. #define GET_DATA_TWO_BYTES(pdata, n) l_getDataTwoBytes(pdata, n)
  163. #define SET_DATA_TWO_BYTES(pdata, n, val) l_setDataTwoBytes(pdata, n, val)
  164. #define GET_DATA_FOUR_BYTES(pdata, n) l_getDataFourBytes(pdata, n)
  165. #define SET_DATA_FOUR_BYTES(pdata, n, val) l_setDataFourBytes(pdata, n, val)
  166. #endif /* !USE_INLINE_ACCESSORS || _MSC_VER */
  167. #endif /* LEPTONICA_ARRAY_ACCESS_H */