diff options
Diffstat (limited to 'leptonica/src/arrayaccess.c')
-rw-r--r-- | leptonica/src/arrayaccess.c | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/leptonica/src/arrayaccess.c b/leptonica/src/arrayaccess.c new file mode 100644 index 00000000..1dd337da --- /dev/null +++ b/leptonica/src/arrayaccess.c @@ -0,0 +1,364 @@ +/*====================================================================* + - Copyright (C) 2001 Leptonica. All rights reserved. + - + - Redistribution and use in source and binary forms, with or without + - modification, are permitted provided that the following conditions + - are met: + - 1. Redistributions of source code must retain the above copyright + - notice, this list of conditions and the following disclaimer. + - 2. Redistributions in binary form must reproduce the above + - copyright notice, this list of conditions and the following + - disclaimer in the documentation and/or other materials + - provided with the distribution. + - + - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY + - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================*/ + +/*! + * \file arrayaccess.c + * <pre> + * + * Access within an array of 32-bit words + * + * l_int32 l_getDataBit() + * void l_setDataBit() + * void l_clearDataBit() + * void l_setDataBitVal() + * l_int32 l_getDataDibit() + * void l_setDataDibit() + * void l_clearDataDibit() + * l_int32 l_getDataQbit() + * void l_setDataQbit() + * void l_clearDataQbit() + * l_int32 l_getDataByte() + * void l_setDataByte() + * l_int32 l_getDataTwoBytes() + * void l_setDataTwoBytes() + * l_int32 l_getDataFourBytes() + * void l_setDataFourBytes() + * + * Note that these all require 32-bit alignment, and hence an input + * ptr to l_uint32. However, this is not enforced by the compiler. + * Instead, we allow the use of a void* ptr, because the line ptrs + * are an efficient way to get random access (see pixGetLinePtrs()). + * It is then necessary to cast internally within each function + * because ptr arithmetic requires knowing the size of the units + * being referenced. + * </pre> + */ + +#ifdef HAVE_CONFIG_H +#include <config_auto.h> +#endif /* HAVE_CONFIG_H */ + +#include "allheaders.h" + +/*----------------------------------------------------------------------* + * Access within an array of 32-bit words * + *----------------------------------------------------------------------*/ +/*! + * \brief l_getDataBit() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return val of the nth 1-bit pixel. + */ +l_int32 +l_getDataBit(const void *line, + l_int32 n) +{ + return (*((const l_uint32 *)line + (n >> 5)) >> (31 - (n & 31))) & 1; +} + + +/*! + * \brief l_setDataBit() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return void + * + * Action: sets the pixel to 1 + */ +void +l_setDataBit(void *line, + l_int32 n) +{ + *((l_uint32 *)line + (n >> 5)) |= (0x80000000 >> (n & 31)); +} + + +/*! + * \brief l_clearDataBit() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return void + * + * Action: sets the 1-bit pixel to 0 + */ +void +l_clearDataBit(void *line, + l_int32 n) +{ + *((l_uint32 *)line + (n >> 5)) &= ~(0x80000000 >> (n & 31)); +} + + +/*! + * \brief l_setDataBitVal() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \param[in] val val to be inserted: 0 or 1 + * \return void + * + * <pre> + * Notes: + * (1) This is an accessor for a 1 bpp pix. + * (2) It is actually a little slower than using: + * if (val == 0) + * l_ClearDataBit(line, n); + * else + * l_SetDataBit(line, n); + * </pre> + */ +void +l_setDataBitVal(void *line, + l_int32 n, + l_int32 val) +{ +l_uint32 *pword; + + pword = (l_uint32 *)line + (n >> 5); + *pword &= ~(0x80000000 >> (n & 31)); /* clear */ + *pword |= (l_uint32)val << (31 - (n & 31)); /* set */ +} + + +/*! + * \brief l_getDataDibit() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return val of the nth 2-bit pixel. + */ +l_int32 +l_getDataDibit(const void *line, + l_int32 n) +{ + return (*((const l_uint32 *)line + (n >> 4)) >> (2 * (15 - (n & 15)))) & 3; +} + + +/*! + * \brief l_setDataDibit() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \param[in] val val to be inserted: 0 - 3 + * \return void + */ +void +l_setDataDibit(void *line, + l_int32 n, + l_int32 val) +{ +l_uint32 *pword; + + pword = (l_uint32 *)line + (n >> 4); + *pword &= ~(0xc0000000 >> (2 * (n & 15))); /* clear */ + *pword |= (l_uint32)(val & 3) << (30 - 2 * (n & 15)); /* set */ +} + + +/*! + * \brief l_clearDataDibit() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return void + * + * Action: sets the 2-bit pixel to 0 + */ +void +l_clearDataDibit(void *line, + l_int32 n) +{ + *((l_uint32 *)line + (n >> 4)) &= ~(0xc0000000 >> (2 * (n & 15))); +} + + +/*! + * \brief l_getDataQbit() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return val of the nth 4-bit pixel. + */ +l_int32 +l_getDataQbit(const void *line, + l_int32 n) +{ + return (*((const l_uint32 *)line + (n >> 3)) >> (4 * (7 - (n & 7)))) & 0xf; +} + + +/*! + * \brief l_setDataQbit() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \param[in] val val to be inserted: 0 - 0xf + * \return void + */ +void +l_setDataQbit(void *line, + l_int32 n, + l_int32 val) +{ +l_uint32 *pword; + + pword = (l_uint32 *)line + (n >> 3); + *pword &= ~(0xf0000000 >> (4 * (n & 7))); /* clear */ + *pword |= (l_uint32)(val & 15) << (28 - 4 * (n & 7)); /* set */ +} + + +/*! + * \brief l_clearDataQbit() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return void + * + * Action: sets the 4-bit pixel to 0 + */ +void +l_clearDataQbit(void *line, + l_int32 n) +{ + *((l_uint32 *)line + (n >> 3)) &= ~(0xf0000000 >> (4 * (n & 7))); +} + + +/*! + * \brief l_getDataByte() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return value of the n-th byte pixel + */ +l_int32 +l_getDataByte(const void *line, + l_int32 n) +{ +#ifdef L_BIG_ENDIAN + return *((const l_uint8 *)line + n); +#else /* L_LITTLE_ENDIAN */ + return *(l_uint8 *)((l_uintptr_t)((const l_uint8 *)line + n) ^ 3); +#endif /* L_BIG_ENDIAN */ +} + + +/*! + * \brief l_setDataByte() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \param[in] val val to be inserted: 0 - 0xff + * \return void + */ +void +l_setDataByte(void *line, + l_int32 n, + l_int32 val) +{ +#ifdef L_BIG_ENDIAN + *((l_uint8 *)line + n) = val; +#else /* L_LITTLE_ENDIAN */ + *(l_uint8 *)((l_uintptr_t)((l_uint8 *)line + n) ^ 3) = val; +#endif /* L_BIG_ENDIAN */ +} + + +/*! + * \brief l_getDataTwoBytes() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return value of the n-th 2-byte pixel + */ +l_int32 +l_getDataTwoBytes(const void *line, + l_int32 n) +{ +#ifdef L_BIG_ENDIAN + return *((const l_uint16 *)line + n); +#else /* L_LITTLE_ENDIAN */ + return *(l_uint16 *)((l_uintptr_t)((const l_uint16 *)line + n) ^ 2); +#endif /* L_BIG_ENDIAN */ +} + + +/*! + * \brief l_setDataTwoBytes() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \param[in] val val to be inserted: 0 - 0xffff + * \return void + */ +void +l_setDataTwoBytes(void *line, + l_int32 n, + l_int32 val) +{ +#ifdef L_BIG_ENDIAN + *((l_uint16 *)line + n) = val; +#else /* L_LITTLE_ENDIAN */ + *(l_uint16 *)((l_uintptr_t)((l_uint16 *)line + n) ^ 2) = val; +#endif /* L_BIG_ENDIAN */ +} + + +/*! + * \brief l_getDataFourBytes() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \return value of the n-th 4-byte pixel + */ +l_int32 +l_getDataFourBytes(const void *line, + l_int32 n) +{ + return *((const l_uint32 *)line + n); +} + + +/*! + * \brief l_setDataFourBytes() + * + * \param[in] line ptr to beginning of data line + * \param[in] n pixel index + * \param[in] val val to be inserted: 0 - 0xffffffff + * \return void + */ +void +l_setDataFourBytes(void *line, + l_int32 n, + l_int32 val) +{ + *((l_uint32 *)line + n) = val; +} |