diff mupdf-source/thirdparty/leptonica/src/arrayaccess.h @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mupdf-source/thirdparty/leptonica/src/arrayaccess.h	Mon Sep 15 11:43:07 2025 +0200
@@ -0,0 +1,270 @@
+/*====================================================================*
+ -  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.
+ *====================================================================*/
+
+#ifndef  LEPTONICA_ARRAY_ACCESS_H
+#define  LEPTONICA_ARRAY_ACCESS_H
+
+/*!
+ * \file arrayaccess.h
+ *
+ * <pre>
+ *  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:
+ * \code
+ *     #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)));}
+ * \endcode
+ *  but if used in an if/else
+ * \code
+ *      if (x)
+ *         SET_DATA_QBIT(...);
+ *      else
+ *         ...
+ * \endcode
+ *  the compiler sees
+ * \code
+ *      if (x)
+ *         {......};
+ *      else
+ *         ...
+ * \endcode
+ *  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.
+ *
+ *  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%.
+ * </pre>
+ */
+
+#define  USE_INLINE_ACCESSORS    1
+
+#if USE_INLINE_ACCESSORS
+
+    /*=============================================================*/
+    /*                Faster: use in line accessors                */
+    /*=============================================================*/
+
+    /*--------------------------------------------------*
+     *                     1 bit access                 *
+     *--------------------------------------------------*/
+/*! 1 bit access - get */
+#define  GET_DATA_BIT(pdata, n) \
+    ((*((const l_uint32 *)(pdata) + ((n) >> 5)) >> (31 - ((n) & 31))) & 1)
+
+/*! 1 bit access - set */
+#define  SET_DATA_BIT(pdata, n) \
+    *((l_uint32 *)(pdata) + ((n) >> 5)) |= (0x80000000 >> ((n) & 31))
+
+/*! 1 bit access - clear */
+#define  CLEAR_DATA_BIT(pdata, n) \
+    *((l_uint32 *)(pdata) + ((n) >> 5)) &= ~(0x80000000 >> ((n) & 31))
+
+/*! 1 bit access - set value (0 or 1) */
+#define  SET_DATA_BIT_VAL(pdata, n, val) \
+     *((l_uint32 *)(pdata) + ((n) >> 5)) = \
+        ((*((l_uint32 *)(pdata) + ((n) >> 5)) \
+        & (~(0x80000000 >> ((n) & 31)))) \
+        | ((l_uint32)(val) << (31 - ((n) & 31))))
+
+    /*--------------------------------------------------*
+     *                     2 bit access                 *
+     *--------------------------------------------------*/
+/*! 2 bit access - get */
+#define  GET_DATA_DIBIT(pdata, n) \
+    ((*((const l_uint32 *)(pdata) + ((n) >> 4)) >> (2 * (15 - ((n) & 15)))) & 3)
+
+/*! 2 bit access - set value (0 ... 3) */
+#define  SET_DATA_DIBIT(pdata, n, val) \
+     *((l_uint32 *)(pdata) + ((n) >> 4)) = \
+        ((*((l_uint32 *)(pdata) + ((n) >> 4)) \
+        & (~(0xc0000000 >> (2 * ((n) & 15))))) \
+        | ((l_uint32)((val) & 3) << (30 - 2 * ((n) & 15))))
+
+/*! 2 bit access - clear */
+#define  CLEAR_DATA_DIBIT(pdata, n) \
+    *((l_uint32 *)(pdata) + ((n) >> 4)) &= ~(0xc0000000 >> (2 * ((n) & 15)))
+
+
+    /*--------------------------------------------------*
+     *                     4 bit access                 *
+     *--------------------------------------------------*/
+/*! 4 bit access - get */
+#define  GET_DATA_QBIT(pdata, n) \
+     ((*((const l_uint32 *)(pdata) + ((n) >> 3)) >> (4 * (7 - ((n) & 7)))) & 0xf)
+
+/*! 4 bit access - set value (0 ... 15) */
+#define  SET_DATA_QBIT(pdata, n, val) \
+     *((l_uint32 *)(pdata) + ((n) >> 3)) = \
+        ((*((l_uint32 *)(pdata) + ((n) >> 3)) \
+        & (~(0xf0000000 >> (4 * ((n) & 7))))) \
+        | ((l_uint32)((val) & 15) << (28 - 4 * ((n) & 7))))
+
+/*! 4 bit access - clear */
+#define  CLEAR_DATA_QBIT(pdata, n) \
+    *((l_uint32 *)(pdata) + ((n) >> 3)) &= ~(0xf0000000 >> (4 * ((n) & 7)))
+
+
+    /*--------------------------------------------------*
+     *                     8 bit access                 *
+     *--------------------------------------------------*/
+#ifdef  L_BIG_ENDIAN
+/*! 8 bit access - get */
+#define  GET_DATA_BYTE(pdata, n) \
+             (*((const l_uint8 *)(pdata) + (n)))
+#else  /* L_LITTLE_ENDIAN */
+/*! 8 bit access - get */
+#define  GET_DATA_BYTE(pdata, n) \
+             (*(l_uint8 *)((l_uintptr_t)((const l_uint8 *)(pdata) + (n)) ^ 3))
+#endif  /* L_BIG_ENDIAN */
+
+#ifdef  L_BIG_ENDIAN
+/*! 8 bit access - set value (0 ... 255) */
+#define  SET_DATA_BYTE(pdata, n, val) \
+             *((l_uint8 *)(pdata) + (n)) = (val)
+#else  /* L_LITTLE_ENDIAN */
+/*! 8 bit access - set value (0 ... 255) */
+#define  SET_DATA_BYTE(pdata, n, val) \
+             *(l_uint8 *)((l_uintptr_t)((l_uint8 *)(pdata) + (n)) ^ 3) = (val)
+#endif  /* L_BIG_ENDIAN */
+
+
+    /*--------------------------------------------------*
+     *                    16 bit access                 *
+     *--------------------------------------------------*/
+#ifdef  L_BIG_ENDIAN
+/*! 16 bit access - get */
+#define  GET_DATA_TWO_BYTES(pdata, n) \
+             (*((const l_uint16 *)(pdata) + (n)))
+#else  /* L_LITTLE_ENDIAN */
+/*! 16 bit access - get */
+#define  GET_DATA_TWO_BYTES(pdata, n) \
+             (*(l_uint16 *)((l_uintptr_t)((const l_uint16 *)(pdata) + (n)) ^ 2))
+#endif  /* L_BIG_ENDIAN */
+
+#ifdef  L_BIG_ENDIAN
+/*! 16 bit access - set value (0 ... 65535) */
+#define  SET_DATA_TWO_BYTES(pdata, n, val) \
+             *((l_uint16 *)(pdata) + (n)) = (val)
+#else  /* L_LITTLE_ENDIAN */
+/*! 16 bit access - set value (0 ... 65535) */
+#define  SET_DATA_TWO_BYTES(pdata, n, val) \
+             *(l_uint16 *)((l_uintptr_t)((l_uint16 *)(pdata) + (n)) ^ 2) = (val)
+#endif  /* L_BIG_ENDIAN */
+
+
+    /*--------------------------------------------------*
+     *                    32 bit access                 *
+     *--------------------------------------------------*/
+/*! 32 bit access - get */
+#define  GET_DATA_FOUR_BYTES(pdata, n) \
+             (*((const l_uint32 *)(pdata) + (n)))
+
+/*! 32 bit access - set (0 ... 4294967295) */
+#define  SET_DATA_FOUR_BYTES(pdata, n, val) \
+             *((l_uint32 *)(pdata) + (n)) = (val)
+
+
+#else
+
+    /*=============================================================*/
+    /*         Slower: use function calls for all accessors        */
+    /*=============================================================*/
+
+#define  GET_DATA_BIT(pdata, n)               l_getDataBit(pdata, n)
+#define  SET_DATA_BIT(pdata, n)               l_setDataBit(pdata, n)
+#define  CLEAR_DATA_BIT(pdata, n)             l_clearDataBit(pdata, n)
+#define  SET_DATA_BIT_VAL(pdata, n, val)      l_setDataBitVal(pdata, n, val)
+
+#define  GET_DATA_DIBIT(pdata, n)             l_getDataDibit(pdata, n)
+#define  SET_DATA_DIBIT(pdata, n, val)        l_setDataDibit(pdata, n, val)
+#define  CLEAR_DATA_DIBIT(pdata, n)           l_clearDataDibit(pdata, n)
+
+#define  GET_DATA_QBIT(pdata, n)              l_getDataQbit(pdata, n)
+#define  SET_DATA_QBIT(pdata, n, val)         l_setDataQbit(pdata, n, val)
+#define  CLEAR_DATA_QBIT(pdata, n)            l_clearDataQbit(pdata, n)
+
+#define  GET_DATA_BYTE(pdata, n)              l_getDataByte(pdata, n)
+#define  SET_DATA_BYTE(pdata, n, val)         l_setDataByte(pdata, n, val)
+
+#define  GET_DATA_TWO_BYTES(pdata, n)         l_getDataTwoBytes(pdata, n)
+#define  SET_DATA_TWO_BYTES(pdata, n, val)    l_setDataTwoBytes(pdata, n, val)
+
+#define  GET_DATA_FOUR_BYTES(pdata, n)         l_getDataFourBytes(pdata, n)
+#define  SET_DATA_FOUR_BYTES(pdata, n, val)    l_setDataFourBytes(pdata, n, val)
+
+#endif  /* USE_INLINE_ACCESSORS */
+
+
+#endif /* LEPTONICA_ARRAY_ACCESS_H */