![]() |
Leptonica
1.82.0
Image processing and image analysis suite
|
Go to the source code of this file.
Macros | |
#define | USE_INLINE_ACCESSORS 1 |
#define | GET_DATA_BIT(pdata, n) ((*((const l_uint32 *)(pdata) + ((n) >> 5)) >> (31 - ((n) & 31))) & 1) |
#define | SET_DATA_BIT(pdata, n) *((l_uint32 *)(pdata) + ((n) >> 5)) |= (0x80000000 >> ((n) & 31)) |
#define | CLEAR_DATA_BIT(pdata, n) *((l_uint32 *)(pdata) + ((n) >> 5)) &= ~(0x80000000 >> ((n) & 31)) |
#define | SET_DATA_BIT_VAL(pdata, n, val) |
#define | GET_DATA_DIBIT(pdata, n) ((*((const l_uint32 *)(pdata) + ((n) >> 4)) >> (2 * (15 - ((n) & 15)))) & 3) |
#define | SET_DATA_DIBIT(pdata, n, val) |
#define | CLEAR_DATA_DIBIT(pdata, n) *((l_uint32 *)(pdata) + ((n) >> 4)) &= ~(0xc0000000 >> (2 * ((n) & 15))) |
#define | GET_DATA_QBIT(pdata, n) ((*((const l_uint32 *)(pdata) + ((n) >> 3)) >> (4 * (7 - ((n) & 7)))) & 0xf) |
#define | SET_DATA_QBIT(pdata, n, val) |
#define | CLEAR_DATA_QBIT(pdata, n) *((l_uint32 *)(pdata) + ((n) >> 3)) &= ~(0xf0000000 >> (4 * ((n) & 7))) |
#define | GET_DATA_BYTE(pdata, n) (*(l_uint8 *)((l_uintptr_t)((const l_uint8 *)(pdata) + (n)) ^ 3)) |
#define | SET_DATA_BYTE(pdata, n, val) *(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3) = (val) |
#define | GET_DATA_TWO_BYTES(pdata, n) (*(l_uint16 *)((l_uintptr_t)((const l_uint16 *)(pdata) + (n)) ^ 2)) |
#define | SET_DATA_TWO_BYTES(pdata, n, val) *(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2) = (val) |
#define | GET_DATA_FOUR_BYTES(pdata, n) (*((const l_uint32 *)(pdata) + (n))) |
#define | SET_DATA_FOUR_BYTES(pdata, n, val) *((l_uint32 *)(pdata) + (n)) = (val) |
1, 2, 4, 8, 16 and 32 bit data access within an array of 32-bit words
This is used primarily to access 1, 2, 4, 8, 16 and 32 bit pixels in a line of image data, represented as an array of 32-bit words.
pdata: pointer to first 32-bit word in the array n: index of the pixel in the array
Function calls for these accessors are defined in arrayaccess.c.
However, for efficiency we use the inline macros for all accesses. Even though the 2 and 4 bit set* accessors are more complicated, they are about 10% faster than the function calls.
The 32 bit access is just a cast and ptr arithmetic. We include it so that the input ptr can be void*.
At the end of this file is code for invoking the function calls instead of inlining.
The macro SET_DATA_BIT_VAL(pdata, n, val) is a bit slower than if (val == 0) CLEAR_DATA_BIT(pdata, n); else SET_DATA_BIT(pdata, n);
Some compilers complain when the SET macros are surrounded by parentheses, because parens require an evaluation and it is not defined for SET macros. If SET_DATA_QBIT were defined as a compound macro, in analogy to l_setDataQbit(), it requires surrounding braces:but if used in an if/else the compiler sees#define SET_DATA_QBIT(pdata, n, val) \{l_uint32 *_TEMP_WORD_PTR_; \_TEMP_WORD_PTR_ = (l_uint32 *)(pdata) + ((n) >> 3); \*_TEMP_WORD_PTR_ &= ~(0xf0000000 >> (4 * ((n) & 7))); \*_TEMP_WORD_PTR_ |= (((val) & 15) << (28 - 4 * ((n) & 7)));}The semicolon comes after the brace and will not compile. This can be fixed in the call by either omitting the semicolon or requiring another set of braces around SET_DATA_QBIT(), but both these options break compatibility with current code, and require special attention by anyone using the macros.if (x){......};else...
There are (at least) two ways to fix this in the macro definitions, suggested by Dave Bryan. (1) Surround the braces in the macro above with do {....} while(0) Then the semicolon just terminates the expression. (2) Reduce the blocks to a single expression; e.g, *((l_uint32 *)(pdata) + ((n) >> 3)) = \ *((l_uint32 *)(pdata) + ((n) >> 3)) \ & ~(0xf0000000 >> (4 * ((n) & 7))) \ | (((val) & 15) << (28 - 4 * ((n) & 7))) This appears to cause redundant computation, but the compiler should evaluate the common subexpression only once. All these methods have the same performance, giving about 300M SET_DATA_QBIT operations per second on a fast 64 bit system. Using the function calls instead of the macros results in about 250M SET_DATA_QBIT operations per second, a performance hit of nearly 20%.
Definition in file arrayaccess.h.
#define CLEAR_DATA_BIT | ( | pdata, | |
n | |||
) | *((l_uint32 *)(pdata) + ((n) >> 5)) &= ~(0x80000000 >> ((n) & 31)) |
1 bit access - clear
Definition at line 131 of file arrayaccess.h.
#define CLEAR_DATA_DIBIT | ( | pdata, | |
n | |||
) | *((l_uint32 *)(pdata) + ((n) >> 4)) &= ~(0xc0000000 >> (2 * ((n) & 15))) |
2 bit access - clear
Definition at line 156 of file arrayaccess.h.
#define CLEAR_DATA_QBIT | ( | pdata, | |
n | |||
) | *((l_uint32 *)(pdata) + ((n) >> 3)) &= ~(0xf0000000 >> (4 * ((n) & 7))) |
4 bit access - clear
Definition at line 175 of file arrayaccess.h.
#define GET_DATA_BIT | ( | pdata, | |
n | |||
) | ((*((const l_uint32 *)(pdata) + ((n) >> 5)) >> (31 - ((n) & 31))) & 1) |
1 bit access - get
Definition at line 123 of file arrayaccess.h.
#define GET_DATA_BYTE | ( | pdata, | |
n | |||
) | (*(l_uint8 *)((l_uintptr_t)((const l_uint8 *)(pdata) + (n)) ^ 3)) |
8 bit access - get
Definition at line 188 of file arrayaccess.h.
#define GET_DATA_DIBIT | ( | pdata, | |
n | |||
) | ((*((const l_uint32 *)(pdata) + ((n) >> 4)) >> (2 * (15 - ((n) & 15)))) & 3) |
2 bit access - get
Definition at line 145 of file arrayaccess.h.
#define GET_DATA_FOUR_BYTES | ( | pdata, | |
n | |||
) | (*((const l_uint32 *)(pdata) + (n))) |
32 bit access - get
Definition at line 231 of file arrayaccess.h.
#define GET_DATA_QBIT | ( | pdata, | |
n | |||
) | ((*((const l_uint32 *)(pdata) + ((n) >> 3)) >> (4 * (7 - ((n) & 7)))) & 0xf) |
4 bit access - get
Definition at line 164 of file arrayaccess.h.
#define GET_DATA_TWO_BYTES | ( | pdata, | |
n | |||
) | (*(l_uint16 *)((l_uintptr_t)((const l_uint16 *)(pdata) + (n)) ^ 2)) |
16 bit access - get
Definition at line 212 of file arrayaccess.h.
#define SET_DATA_BIT | ( | pdata, | |
n | |||
) | *((l_uint32 *)(pdata) + ((n) >> 5)) |= (0x80000000 >> ((n) & 31)) |
1 bit access - set
Definition at line 127 of file arrayaccess.h.
#define SET_DATA_BIT_VAL | ( | pdata, | |
n, | |||
val | |||
) |
1 bit access - set value (0 or 1)
Definition at line 135 of file arrayaccess.h.
#define SET_DATA_BYTE | ( | pdata, | |
n, | |||
val | |||
) | *(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3) = (val) |
8 bit access - set value (0 ... 255)
Definition at line 198 of file arrayaccess.h.
#define SET_DATA_DIBIT | ( | pdata, | |
n, | |||
val | |||
) |
2 bit access - set value (0 ... 3)
Definition at line 149 of file arrayaccess.h.
#define SET_DATA_FOUR_BYTES | ( | pdata, | |
n, | |||
val | |||
) | *((l_uint32 *)(pdata) + (n)) = (val) |
32 bit access - set (0 ... 4294967295)
Definition at line 235 of file arrayaccess.h.
#define SET_DATA_QBIT | ( | pdata, | |
n, | |||
val | |||
) |
4 bit access - set value (0 ... 15)
Definition at line 168 of file arrayaccess.h.
#define SET_DATA_TWO_BYTES | ( | pdata, | |
n, | |||
val | |||
) | *(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2) = (val) |
16 bit access - set value (0 ... 65535)
Definition at line 222 of file arrayaccess.h.