blob: e0ec1a80e59c2a67c12043889ee4fe19502e42db [file] [log] [blame]
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
- This software is distributed in the hope that it will be
- useful, but with NO WARRANTY OF ANY KIND.
- No author or distributor accepts responsibility to anyone for the
- consequences of using this software, or for whether it serves any
- particular purpose or works at all, unless he or she says so in
- writing. Everyone is granted permission to copy, modify and
- redistribute this source code, for commercial or non-commercial
- purposes, with the following restrictions: (1) the origin of this
- source code must not be misrepresented; (2) modified versions must
- be plainly marked as such; and (3) this notice may not be removed
- or altered from any source or modified source distribution.
*====================================================================*/
/*
* arrayaccess.c
*
* 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.
*/
#include <stdio.h>
#include "allheaders.h"
/*----------------------------------------------------------------------*
* Access within an array of 32-bit words *
*----------------------------------------------------------------------*/
/*!
* l_getDataBit()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* Return: val of the nth (1-bit) pixel.
*/
l_int32
l_getDataBit(void *line,
l_int32 n)
{
return (*((l_uint32 *)line + (n >> 5)) >> (31 - (n & 31))) & 1;
}
/*!
* l_setDataBit()
*
* Input: line (ptr to beginning of data line)
* 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));
}
/*!
* l_clearDataBit()
*
* Input: line (ptr to beginning of data line)
* 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));
}
/*!
* l_setDataBitVal()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* val (val to be inserted: 0 - 3)
* Return: void
*
* Notes:
* (1) This is actually a little slower than using:
* if (val == 0)
* l_ClearDataBit(line, n);
* else
* l_SetDataBit(line, n);
*/
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 |= val << (31 - (n & 31)); /* set */
return;
}
/*!
* l_getDataDibit()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* Return: val of the nth (2-bit) pixel.
*/
l_int32
l_getDataDibit(void *line,
l_int32 n)
{
return (*((l_uint32 *)line + (n >> 4)) >> (2 * (15 - (n & 15)))) & 3;
}
/*!
* l_setDataDibit()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* 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 |= val << (30 - 2 * (n & 15)); /* set */
return;
}
/*!
* l_clearDataDibit()
*
* Input: line (ptr to beginning of data line)
* 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)));
}
/*!
* l_getDataQbit()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* Return: val of the nth (4-bit) pixel.
*/
l_int32
l_getDataQbit(void *line,
l_int32 n)
{
return (*((l_uint32 *)line + (n >> 3)) >> (4 * (7 - (n & 7)))) & 0xf;
}
/*!
* l_setDataQbit()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* 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 |= val << (28 - 4 * (n & 7)); /* set */
return;
}
/*!
* l_clearDataQbit()
*
* Input: line (ptr to beginning of data line)
* 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)));
}
/*!
* l_getDataByte()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* Return: value of the n-th (byte) pixel
*/
l_int32
l_getDataByte(void *line,
l_int32 n)
{
#ifdef L_BIG_ENDIAN
return *((l_uint8 *)line + n);
#else /* L_LITTLE_ENDIAN */
return *(l_uint8 *)((l_uintptr_t)((l_uint8 *)line + n) ^ 3);
#endif /* L_BIG_ENDIAN */
}
/*!
* l_setDataByte()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* 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 */
}
/*!
* l_getDataTwoBytes()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* Return: value of the n-th (2-byte) pixel
*/
l_int32
l_getDataTwoBytes(void *line,
l_int32 n)
{
#ifdef L_BIG_ENDIAN
return *((l_uint16 *)line + n);
#else /* L_LITTLE_ENDIAN */
return *(l_uint16 *)((l_uintptr_t)((l_uint16 *)line + n) ^ 2);
#endif /* L_BIG_ENDIAN */
}
/*!
* l_setDataTwoBytes()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* 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 */
}
/*!
* l_getDataFourBytes()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* Return: value of the n-th (4-byte) pixel
*/
l_int32
l_getDataFourBytes(void *line,
l_int32 n)
{
return *((l_uint32 *)line + n);
}
/*!
* l_setDataFourBytes()
*
* Input: line (ptr to beginning of data line)
* n (pixel index)
* 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;
}