Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/leptonica/src/pixacc.c @ 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 |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 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 | |
| 27 /*! | |
| 28 * \file pixacc.c | |
| 29 * <pre> | |
| 30 * | |
| 31 * Pixacc creation, destruction | |
| 32 * PIXACC *pixaccCreate() | |
| 33 * PIXACC *pixaccCreateFromPix() | |
| 34 * void pixaccDestroy() | |
| 35 * | |
| 36 * Pixacc finalization | |
| 37 * PIX *pixaccFinal() | |
| 38 * | |
| 39 * Pixacc accessors | |
| 40 * PIX *pixaccGetPix() | |
| 41 * l_int32 pixaccGetOffset() | |
| 42 * | |
| 43 * Pixacc accumulators | |
| 44 * l_int32 pixaccAdd() | |
| 45 * l_int32 pixaccSubtract() | |
| 46 * l_int32 pixaccMultConst() | |
| 47 * l_int32 pixaccMultConstAccumulate() | |
| 48 * | |
| 49 * This is a simple interface for some of the pixel arithmetic operations | |
| 50 * in pixarith.c. These are easy to code up, but not as fast as | |
| 51 * hand-coded functions that do arithmetic on corresponding pixels. | |
| 52 * | |
| 53 * Suppose you want to make a linear combination of pix1 and pix2: | |
| 54 * pixd = 0.4 * pix1 + 0.6 * pix2 | |
| 55 * where pix1 and pix2 are the same size and have depth 'd'. Then: | |
| 56 * Pixacc *pacc = pixaccCreateFromPix(pix1, 0); // first; addition only | |
| 57 * pixaccMultConst(pacc, 0.4); | |
| 58 * pixaccMultConstAccumulate(pacc, pix2, 0.6); // Add in 0.6 of the second | |
| 59 * pixd = pixaccFinal(pacc, d); // Get the result | |
| 60 * pixaccDestroy(&pacc); | |
| 61 * </pre> | |
| 62 */ | |
| 63 | |
| 64 #ifdef HAVE_CONFIG_H | |
| 65 #include <config_auto.h> | |
| 66 #endif /* HAVE_CONFIG_H */ | |
| 67 | |
| 68 #include "allheaders.h" | |
| 69 #include "pix_internal.h" | |
| 70 | |
| 71 /*---------------------------------------------------------------------* | |
| 72 * Pixacc creation, destruction * | |
| 73 *---------------------------------------------------------------------*/ | |
| 74 /*! | |
| 75 * \brief pixaccCreate() | |
| 76 * | |
| 77 * \param[in] w, h of 32 bpp internal Pix | |
| 78 * \param[in] negflag 0 if only positive numbers are involved; | |
| 79 * 1 if there will be negative numbers | |
| 80 * \return pixacc, or NULL on error | |
| 81 * | |
| 82 * <pre> | |
| 83 * Notes: | |
| 84 * (1) Use %negflag = 1 for safety if any negative numbers are going | |
| 85 * to be used in the chain of operations. Negative numbers | |
| 86 * arise, e.g., by subtracting a pix, or by adding a pix | |
| 87 * that has been pre-multiplied by a negative number. | |
| 88 * (2) Initializes the internal 32 bpp pix, similarly to the | |
| 89 * initialization in pixInitAccumulate(). | |
| 90 * </pre> | |
| 91 */ | |
| 92 PIXACC * | |
| 93 pixaccCreate(l_int32 w, | |
| 94 l_int32 h, | |
| 95 l_int32 negflag) | |
| 96 { | |
| 97 PIXACC *pixacc; | |
| 98 | |
| 99 pixacc = (PIXACC *)LEPT_CALLOC(1, sizeof(PIXACC)); | |
| 100 pixacc->w = w; | |
| 101 pixacc->h = h; | |
| 102 | |
| 103 if ((pixacc->pix = pixCreate(w, h, 32)) == NULL) { | |
| 104 pixaccDestroy(&pixacc); | |
| 105 return (PIXACC *)ERROR_PTR("pix not made", __func__, NULL); | |
| 106 } | |
| 107 | |
| 108 if (negflag) { | |
| 109 pixacc->offset = 0x40000000; | |
| 110 pixSetAllArbitrary(pixacc->pix, pixacc->offset); | |
| 111 } | |
| 112 | |
| 113 return pixacc; | |
| 114 } | |
| 115 | |
| 116 | |
| 117 /*! | |
| 118 * \brief pixaccCreateFromPix() | |
| 119 * | |
| 120 * \param[in] pix | |
| 121 * \param[in] negflag 0 if only positive numbers are involved; | |
| 122 * 1 if there will be negative numbers | |
| 123 * \return pixacc, or NULL on error | |
| 124 * | |
| 125 * <pre> | |
| 126 * Notes: | |
| 127 * (1) See pixaccCreate() | |
| 128 * </pre> | |
| 129 */ | |
| 130 PIXACC * | |
| 131 pixaccCreateFromPix(PIX *pix, | |
| 132 l_int32 negflag) | |
| 133 { | |
| 134 l_int32 w, h; | |
| 135 PIXACC *pixacc; | |
| 136 | |
| 137 if (!pix) | |
| 138 return (PIXACC *)ERROR_PTR("pix not defined", __func__, NULL); | |
| 139 | |
| 140 pixGetDimensions(pix, &w, &h, NULL); | |
| 141 pixacc = pixaccCreate(w, h, negflag); | |
| 142 pixaccAdd(pixacc, pix); | |
| 143 return pixacc; | |
| 144 } | |
| 145 | |
| 146 | |
| 147 /*! | |
| 148 * \brief pixaccDestroy() | |
| 149 * | |
| 150 * \param[in,out] ppixacc will be set to null before returning | |
| 151 * \return void | |
| 152 * | |
| 153 * <pre> | |
| 154 * Notes: | |
| 155 * (1) Always nulls the input ptr. | |
| 156 * </pre> | |
| 157 */ | |
| 158 void | |
| 159 pixaccDestroy(PIXACC **ppixacc) | |
| 160 { | |
| 161 PIXACC *pixacc; | |
| 162 | |
| 163 if (ppixacc == NULL) { | |
| 164 L_WARNING("ptr address is NULL!", __func__); | |
| 165 return; | |
| 166 } | |
| 167 | |
| 168 if ((pixacc = *ppixacc) == NULL) | |
| 169 return; | |
| 170 | |
| 171 pixDestroy(&pixacc->pix); | |
| 172 LEPT_FREE(pixacc); | |
| 173 *ppixacc = NULL; | |
| 174 } | |
| 175 | |
| 176 | |
| 177 /*---------------------------------------------------------------------* | |
| 178 * Pixacc finalization * | |
| 179 *---------------------------------------------------------------------*/ | |
| 180 /*! | |
| 181 * \brief pixaccFinal() | |
| 182 * | |
| 183 * \param[in] pixacc | |
| 184 * \param[in] outdepth 8, 16 or 32 bpp | |
| 185 * \return pixd 8, 16 or 32 bpp, or NULL on error | |
| 186 */ | |
| 187 PIX * | |
| 188 pixaccFinal(PIXACC *pixacc, | |
| 189 l_int32 outdepth) | |
| 190 { | |
| 191 if (!pixacc) | |
| 192 return (PIX *)ERROR_PTR("pixacc not defined", __func__, NULL); | |
| 193 | |
| 194 return pixFinalAccumulate(pixaccGetPix(pixacc), pixaccGetOffset(pixacc), | |
| 195 outdepth); | |
| 196 } | |
| 197 | |
| 198 | |
| 199 /*---------------------------------------------------------------------* | |
| 200 * Pixacc accessors * | |
| 201 *---------------------------------------------------------------------*/ | |
| 202 /*! | |
| 203 * \brief pixaccGetPix() | |
| 204 * | |
| 205 * \param[in] pixacc | |
| 206 * \return pix, or NULL on error | |
| 207 */ | |
| 208 PIX * | |
| 209 pixaccGetPix(PIXACC *pixacc) | |
| 210 { | |
| 211 if (!pixacc) | |
| 212 return (PIX *)ERROR_PTR("pixacc not defined", __func__, NULL); | |
| 213 return pixacc->pix; | |
| 214 } | |
| 215 | |
| 216 | |
| 217 /*! | |
| 218 * \brief pixaccGetOffset() | |
| 219 * | |
| 220 * \param[in] pixacc | |
| 221 * \return offset, or -1 on error | |
| 222 */ | |
| 223 l_int32 | |
| 224 pixaccGetOffset(PIXACC *pixacc) | |
| 225 { | |
| 226 if (!pixacc) | |
| 227 return ERROR_INT("pixacc not defined", __func__, -1); | |
| 228 return pixacc->offset; | |
| 229 } | |
| 230 | |
| 231 | |
| 232 /*---------------------------------------------------------------------* | |
| 233 * Pixacc accumulators * | |
| 234 *---------------------------------------------------------------------*/ | |
| 235 /*! | |
| 236 * \brief pixaccAdd() | |
| 237 * | |
| 238 * \param[in] pixacc | |
| 239 * \param[in] pix to be added | |
| 240 * \return 0 if OK, 1 on error | |
| 241 */ | |
| 242 l_ok | |
| 243 pixaccAdd(PIXACC *pixacc, | |
| 244 PIX *pix) | |
| 245 { | |
| 246 if (!pixacc) | |
| 247 return ERROR_INT("pixacc not defined", __func__, 1); | |
| 248 if (!pix) | |
| 249 return ERROR_INT("pix not defined", __func__, 1); | |
| 250 pixAccumulate(pixaccGetPix(pixacc), pix, L_ARITH_ADD); | |
| 251 return 0; | |
| 252 } | |
| 253 | |
| 254 | |
| 255 /*! | |
| 256 * \brief pixaccSubtract() | |
| 257 * | |
| 258 * \param[in] pixacc | |
| 259 * \param[in] pix to be subtracted | |
| 260 * \return 0 if OK, 1 on error | |
| 261 */ | |
| 262 l_ok | |
| 263 pixaccSubtract(PIXACC *pixacc, | |
| 264 PIX *pix) | |
| 265 { | |
| 266 if (!pixacc) | |
| 267 return ERROR_INT("pixacc not defined", __func__, 1); | |
| 268 if (!pix) | |
| 269 return ERROR_INT("pix not defined", __func__, 1); | |
| 270 pixAccumulate(pixaccGetPix(pixacc), pix, L_ARITH_SUBTRACT); | |
| 271 return 0; | |
| 272 } | |
| 273 | |
| 274 | |
| 275 /*! | |
| 276 * \brief pixaccMultConst() | |
| 277 * | |
| 278 * \param[in] pixacc | |
| 279 * \param[in] factor | |
| 280 * \return 0 if OK, 1 on error | |
| 281 */ | |
| 282 l_ok | |
| 283 pixaccMultConst(PIXACC *pixacc, | |
| 284 l_float32 factor) | |
| 285 { | |
| 286 if (!pixacc) | |
| 287 return ERROR_INT("pixacc not defined", __func__, 1); | |
| 288 pixMultConstAccumulate(pixaccGetPix(pixacc), factor, | |
| 289 pixaccGetOffset(pixacc)); | |
| 290 return 0; | |
| 291 } | |
| 292 | |
| 293 | |
| 294 /*! | |
| 295 * \brief pixaccMultConstAccumulate() | |
| 296 * | |
| 297 * \param[in] pixacc | |
| 298 * \param[in] pix | |
| 299 * \param[in] factor | |
| 300 * \return 0 if OK, 1 on error | |
| 301 * | |
| 302 * <pre> | |
| 303 * Notes: | |
| 304 * (1) This creates a temp pix that is %pix multiplied by the | |
| 305 * constant %factor. It then adds that into %pixacc. | |
| 306 * </pre> | |
| 307 */ | |
| 308 l_ok | |
| 309 pixaccMultConstAccumulate(PIXACC *pixacc, | |
| 310 PIX *pix, | |
| 311 l_float32 factor) | |
| 312 { | |
| 313 l_int32 w, h, d, negflag; | |
| 314 PIX *pixt; | |
| 315 PIXACC *pacct; | |
| 316 | |
| 317 if (!pixacc) | |
| 318 return ERROR_INT("pixacc not defined", __func__, 1); | |
| 319 if (!pix) | |
| 320 return ERROR_INT("pix not defined", __func__, 1); | |
| 321 | |
| 322 if (factor == 0.0) return 0; | |
| 323 | |
| 324 pixGetDimensions(pix, &w, &h, &d); | |
| 325 negflag = (factor > 0.0) ? 0 : 1; | |
| 326 pacct = pixaccCreate(w, h, negflag); | |
| 327 pixaccAdd(pacct, pix); | |
| 328 pixaccMultConst(pacct, factor); | |
| 329 pixt = pixaccFinal(pacct, d); | |
| 330 pixaccAdd(pixacc, pixt); | |
| 331 | |
| 332 pixaccDestroy(&pacct); | |
| 333 pixDestroy(&pixt); | |
| 334 return 0; | |
| 335 } |
