Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/leptonica/src/flipdetectdwa.c.notused @ 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 flipdetectdwa.c.notused | |
| 29 * <pre> | |
| 30 * | |
| 31 * NOTE | |
| 32 * ============================================================== | |
| 33 * This code has been retired from the library. It is faster than | |
| 34 * the rasterop implementation, but not by a large amount. On a | |
| 35 * standard 8 Mpixel page image, the timings are: | |
| 36 * Rasterop: 0.37 sec | |
| 37 * DWA: 0.21 sec. | |
| 38 * It is preserved here to show how the dwa code can be generated | |
| 39 * and then used in an application. | |
| 40 * ============================================================== | |
| 41 * | |
| 42 * DWA page orientation detection (pure rotation by 90 degree increments): | |
| 43 * l_int32 pixOrientDetectDwa() | |
| 44 * l_int32 pixUpDownDetectDwa() | |
| 45 * | |
| 46 * DWA mirror detection (flip 180 degrees about line in plane of image): | |
| 47 * l_int32 pixMirrorDetectDwa() | |
| 48 * | |
| 49 * Low-level auto-generated DWA implementation of hit-miss transforms. | |
| 50 * This code (rearranged) was generated by prog/flipselgen.c. | |
| 51 * static PIX *pixFlipFHMTGen() | |
| 52 * --> static l_int32 flipfhmtgen_low() -- dispatcher | |
| 53 * --> static void fhmt_1_0() | |
| 54 * --> static void fhmt_1_1() | |
| 55 * --> static void fhmt_1_2() | |
| 56 * --> static void fhmt_1_3() | |
| 57 * | |
| 58 * The four Sels used are defined in prog/flipselgen.c. | |
| 59 * They are the same as those in flipdetect.c. | |
| 60 * </pre> | |
| 61 */ | |
| 62 | |
| 63 #ifdef HAVE_CONFIG_H | |
| 64 #include <config_auto.h> | |
| 65 #endif /* HAVE_CONFIG_H */ | |
| 66 | |
| 67 #include <math.h> | |
| 68 #include <string.h> | |
| 69 #include "allheaders.h" | |
| 70 | |
| 71 /* Parameters for determining orientation */ | |
| 72 static const l_int32 DefaultMinUpDownCount = 70; | |
| 73 static const l_float32 DefaultMinUpDownConf = 8.0; | |
| 74 | |
| 75 /* Parameters for determining mirror flip */ | |
| 76 static const l_int32 DefaultMinMirrorFlipCount = 100; | |
| 77 static const l_float32 DefaultMinMirrorFlipConf = 5.0; | |
| 78 | |
| 79 static l_int32 NUM_SELS_GENERATED = 4; | |
| 80 static char SEL_NAMES[][10] = {"flipsel1", | |
| 81 "flipsel2", | |
| 82 "flipsel3", | |
| 83 "flipsel4"}; | |
| 84 | |
| 85 static l_int32 flipfhmtgen_low(l_uint32 *, l_int32, l_int32, l_int32, | |
| 86 l_uint32 *, l_int32, l_int32); | |
| 87 | |
| 88 static void fhmt_1_0(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, | |
| 89 l_int32); | |
| 90 static void fhmt_1_1(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, | |
| 91 l_int32); | |
| 92 static void fhmt_1_2(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, | |
| 93 l_int32); | |
| 94 static void fhmt_1_3(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, | |
| 95 l_int32); | |
| 96 | |
| 97 /*----------------------------------------------------------------* | |
| 98 * High-level interface for orientation detection * | |
| 99 * (four 90 degree angles) * | |
| 100 *----------------------------------------------------------------*/ | |
| 101 /*! | |
| 102 * \brief pixOrientDetectDwa() | |
| 103 * | |
| 104 * \param[in] pixs 1 bpp, deskewed, English text | |
| 105 * \param[out] pupconf [optional] ; may be NULL | |
| 106 * \param[out] pleftconf [optional] ; may be NULL | |
| 107 * \param[in] mincount min number of up + down; use 0 for default | |
| 108 * \param[in] debug 1 for debug output; 0 otherwise | |
| 109 * \return 0 if OK, 1 on error | |
| 110 * | |
| 111 * <pre> | |
| 112 * Notes: | |
| 113 * (1) Same interface as for pixOrientDetect(). See notes | |
| 114 * there for usage. | |
| 115 * (2) Uses auto-gen'd code for the Sels defined at the | |
| 116 * top of this file, with some renaming of functions. | |
| 117 * The auto-gen'd code is in fliphmtgen.c, and can | |
| 118 * be generated by a simple executable; see prog/flipselgen.c. | |
| 119 * (3) This runs about 1.5 times faster than the pixOrientDetect(). | |
| 120 * </pre> | |
| 121 */ | |
| 122 l_ok | |
| 123 pixOrientDetectDwa(PIX *pixs, | |
| 124 l_float32 *pupconf, | |
| 125 l_float32 *pleftconf, | |
| 126 l_int32 mincount, | |
| 127 l_int32 debug) | |
| 128 { | |
| 129 PIX *pix1; | |
| 130 | |
| 131 if (!pixs || pixGetDepth(pixs) != 1) | |
| 132 return ERROR_INT("pixs not defined or not 1 bpp", __func__, 1); | |
| 133 if (!pupconf && !pleftconf) | |
| 134 return ERROR_INT("nothing to do", __func__, 1); | |
| 135 if (mincount == 0) | |
| 136 mincount = DefaultMinUpDownCount; | |
| 137 | |
| 138 if (pupconf) | |
| 139 pixUpDownDetectDwa(pixs, pupconf, mincount, 0, debug); | |
| 140 if (pleftconf) { | |
| 141 pix1 = pixRotate90(pixs, 1); | |
| 142 pixUpDownDetectDwa(pix1, pleftconf, mincount, 0, debug); | |
| 143 pixDestroy(&pix1); | |
| 144 } | |
| 145 | |
| 146 return 0; | |
| 147 } | |
| 148 | |
| 149 | |
| 150 /*! | |
| 151 * \brief pixUpDownDetectDwa() | |
| 152 * | |
| 153 * \param[in] pixs 1 bpp, deskewed, English text, 150 - 300 ppi | |
| 154 * \param[out] pconf confidence that text is rightside-up | |
| 155 * \param[in] mincount min number of up + down; use 0 for default | |
| 156 * \param[in] npixels number of pixels removed from each side of word box | |
| 157 * \param[in] debug 1 for debug output; 0 otherwise | |
| 158 * \return 0 if OK, 1 on error | |
| 159 * | |
| 160 * <pre> | |
| 161 * Notes: | |
| 162 * (1) Faster (DWA) version of pixUpDownDetect(). | |
| 163 * (2) If npixels == 0, the pixels identified through the HMT | |
| 164 * (hit-miss transform) are not clipped by a truncated word | |
| 165 * mask pixm. See pixUpDownDetect() for usage and other details. | |
| 166 * (3) The returned confidence is the normalized difference | |
| 167 * between the number of detected up and down ascenders, | |
| 168 * assuming that the text is either rightside-up or upside-down | |
| 169 * and not rotated at a 90 degree angle. | |
| 170 * </pre> | |
| 171 */ | |
| 172 l_ok | |
| 173 pixUpDownDetectDwa(PIX *pixs, | |
| 174 l_float32 *pconf, | |
| 175 l_int32 mincount, | |
| 176 l_int32 npixels, | |
| 177 l_int32 debug) | |
| 178 { | |
| 179 char flipsel1[] = "flipsel1"; | |
| 180 char flipsel2[] = "flipsel2"; | |
| 181 char flipsel3[] = "flipsel3"; | |
| 182 char flipsel4[] = "flipsel4"; | |
| 183 l_int32 countup, countdown, nmax; | |
| 184 l_float32 nup, ndown; | |
| 185 PIX *pixt, *pix0, *pix1, *pix2, *pix3, *pixm; | |
| 186 | |
| 187 if (!pconf) | |
| 188 return ERROR_INT("&conf not defined", __func__, 1); | |
| 189 *pconf = 0.0; | |
| 190 if (!pixs || pixGetDepth(pixs) != 1) | |
| 191 return ERROR_INT("pixs not defined or not 1 bpp", __func__, 1); | |
| 192 if (mincount == 0) | |
| 193 mincount = DefaultMinUpDownCount; | |
| 194 if (npixels < 0) | |
| 195 npixels = 0; | |
| 196 | |
| 197 /* One of many reasonable pre-filtering sequences: (1, 8) and (30, 1). | |
| 198 * This closes holes in x-height characters and joins them at | |
| 199 * the x-height. There is more noise in the descender detection | |
| 200 * from this, but it works fairly well. */ | |
| 201 pixt = pixMorphSequenceDwa(pixs, "c1.8 + c30.1", 0); | |
| 202 | |
| 203 /* Be sure to add the border before the flip DWA operations! */ | |
| 204 pix0 = pixAddBorderGeneral(pixt, ADDED_BORDER, ADDED_BORDER, | |
| 205 ADDED_BORDER, ADDED_BORDER, 0); | |
| 206 pixDestroy(&pixt); | |
| 207 | |
| 208 /* Optionally, make a mask of the word bounding boxes, shortening | |
| 209 * each of them by a fixed amount at each end. */ | |
| 210 pixm = NULL; | |
| 211 if (npixels > 0) { | |
| 212 l_int32 i, nbox, x, y, w, h; | |
| 213 BOX *box; | |
| 214 BOXA *boxa; | |
| 215 pix1 = pixMorphSequenceDwa(pix0, "o10.1", 0); | |
| 216 boxa = pixConnComp(pix1, NULL, 8); | |
| 217 pixm = pixCreateTemplate(pix1); | |
| 218 pixDestroy(&pix1); | |
| 219 nbox = boxaGetCount(boxa); | |
| 220 for (i = 0; i < nbox; i++) { | |
| 221 box = boxaGetBox(boxa, i, L_CLONE); | |
| 222 boxGetGeometry(box, &x, &y, &w, &h); | |
| 223 if (w > 2 * npixels) | |
| 224 pixRasterop(pixm, x + npixels, y - 6, w - 2 * npixels, h + 13, | |
| 225 PIX_SET, NULL, 0, 0); | |
| 226 boxDestroy(&box); | |
| 227 } | |
| 228 boxaDestroy(&boxa); | |
| 229 } | |
| 230 | |
| 231 /* Find the ascenders and optionally filter with pixm. | |
| 232 * For an explanation of the procedure used for counting the result | |
| 233 * of the HMT, see comments in pixUpDownDetect(). */ | |
| 234 pix1 = pixFlipFHMTGen(NULL, pix0, flipsel1); | |
| 235 pix2 = pixFlipFHMTGen(NULL, pix0, flipsel2); | |
| 236 pixOr(pix1, pix1, pix2); | |
| 237 if (pixm) | |
| 238 pixAnd(pix1, pix1, pixm); | |
| 239 pix3 = pixReduceRankBinaryCascade(pix1, 1, 1, 0, 0); | |
| 240 pixCountPixels(pix3, &countup, NULL); | |
| 241 pixDestroy(&pix1); | |
| 242 pixDestroy(&pix2); | |
| 243 pixDestroy(&pix3); | |
| 244 | |
| 245 /* Find the ascenders and optionally filter with pixm. */ | |
| 246 pix1 = pixFlipFHMTGen(NULL, pix0, flipsel3); | |
| 247 pix2 = pixFlipFHMTGen(NULL, pix0, flipsel4); | |
| 248 pixOr(pix1, pix1, pix2); | |
| 249 if (pixm) | |
| 250 pixAnd(pix1, pix1, pixm); | |
| 251 pix3 = pixReduceRankBinaryCascade(pix1, 1, 1, 0, 0); | |
| 252 pixCountPixels(pix3, &countdown, NULL); | |
| 253 pixDestroy(&pix1); | |
| 254 pixDestroy(&pix2); | |
| 255 pixDestroy(&pix3); | |
| 256 | |
| 257 /* Evaluate statistically, generating a confidence that is | |
| 258 * related to the probability with a gaussian distribution. */ | |
| 259 nup = (l_float32)(countup); | |
| 260 ndown = (l_float32)(countdown); | |
| 261 nmax = L_MAX(countup, countdown); | |
| 262 if (nmax > mincount) | |
| 263 *pconf = 2. * ((nup - ndown) / sqrt(nup + ndown)); | |
| 264 | |
| 265 if (debug) { | |
| 266 if (pixm) { | |
| 267 lept_mkdir("lept/orient"); | |
| 268 pixWriteDebug("/tmp/lept/orient/pixm2.png", pixm, IFF_PNG); | |
| 269 } | |
| 270 lept_stderr("nup = %7.3f, ndown = %7.3f, conf = %7.3f\n", | |
| 271 nup, ndown, *pconf); | |
| 272 if (*pconf > DefaultMinUpDownConf) | |
| 273 lept_stderr("Text is rightside-up\n"); | |
| 274 if (*pconf < -DefaultMinUpDownConf) | |
| 275 lept_stderr("Text is upside-down\n"); | |
| 276 } | |
| 277 | |
| 278 pixDestroy(&pix0); | |
| 279 pixDestroy(&pixm); | |
| 280 return 0; | |
| 281 } | |
| 282 | |
| 283 | |
| 284 /*----------------------------------------------------------------* | |
| 285 * Left-right mirror detection * | |
| 286 * DWA implementation * | |
| 287 *----------------------------------------------------------------*/ | |
| 288 /*! | |
| 289 * \brief pixMirrorDetectDwa() | |
| 290 * | |
| 291 * \param[in] pixs 1 bpp, deskewed, English text | |
| 292 * \param[out] pconf confidence that text is not LR mirror reversed | |
| 293 * \param[in] mincount min number of left + right; use 0 for default | |
| 294 * \param[in] debug 1 for debug output; 0 otherwise | |
| 295 * \return 0 if OK, 1 on error | |
| 296 * | |
| 297 * <pre> | |
| 298 * Notes: | |
| 299 * (1) We assume the text is horizontally oriented, with | |
| 300 * ascenders going up. | |
| 301 * (2) See notes in pixMirrorDetect(). | |
| 302 * </pre> | |
| 303 */ | |
| 304 l_ok | |
| 305 pixMirrorDetectDwa(PIX *pixs, | |
| 306 l_float32 *pconf, | |
| 307 l_int32 mincount, | |
| 308 l_int32 debug) | |
| 309 { | |
| 310 char flipsel1[] = "flipsel1"; | |
| 311 char flipsel2[] = "flipsel2"; | |
| 312 l_int32 count1, count2, nmax; | |
| 313 l_float32 nleft, nright; | |
| 314 PIX *pix0, *pix1, *pix2, *pix3; | |
| 315 | |
| 316 if (!pconf) | |
| 317 return ERROR_INT("&conf not defined", __func__, 1); | |
| 318 *pconf = 0.0; | |
| 319 if (!pixs || pixGetDepth(pixs) != 1) | |
| 320 return ERROR_INT("pixs not defined or not 1 bpp", __func__, 1); | |
| 321 if (mincount == 0) | |
| 322 mincount = DefaultMinMirrorFlipCount; | |
| 323 | |
| 324 /* Fill x-height characters but not space between them, sort of. */ | |
| 325 pix3 = pixMorphSequenceDwa(pixs, "d1.30", 0); | |
| 326 pixXor(pix3, pix3, pixs); | |
| 327 pix0 = pixMorphSequenceDwa(pixs, "c15.1", 0); | |
| 328 pixXor(pix0, pix0, pixs); | |
| 329 pixAnd(pix0, pix0, pix3); | |
| 330 pixOr(pix3, pix0, pixs); | |
| 331 pixDestroy(&pix0); | |
| 332 pix0 = pixAddBorderGeneral(pix3, ADDED_BORDER, ADDED_BORDER, | |
| 333 ADDED_BORDER, ADDED_BORDER, 0); | |
| 334 pixDestroy(&pix3); | |
| 335 | |
| 336 /* Filter the right-facing characters. */ | |
| 337 pix1 = pixFlipFHMTGen(NULL, pix0, flipsel1); | |
| 338 pix3 = pixReduceRankBinaryCascade(pix1, 1, 1, 0, 0); | |
| 339 pixCountPixels(pix3, &count1, NULL); | |
| 340 pixDestroy(&pix1); | |
| 341 pixDestroy(&pix3); | |
| 342 | |
| 343 /* Filter the left-facing characters. */ | |
| 344 pix2 = pixFlipFHMTGen(NULL, pix0, flipsel2); | |
| 345 pix3 = pixReduceRankBinaryCascade(pix2, 1, 1, 0, 0); | |
| 346 pixCountPixels(pix3, &count2, NULL); | |
| 347 pixDestroy(&pix2); | |
| 348 pixDestroy(&pix3); | |
| 349 | |
| 350 pixDestroy(&pix0); | |
| 351 nright = (l_float32)count1; | |
| 352 nleft = (l_float32)count2; | |
| 353 nmax = L_MAX(count1, count2); | |
| 354 | |
| 355 if (nmax > mincount) | |
| 356 *pconf = 2. * ((nright - nleft) / sqrt(nright + nleft)); | |
| 357 | |
| 358 if (debug) { | |
| 359 lept_stderr("nright = %f, nleft = %f\n", nright, nleft); | |
| 360 if (*pconf > DefaultMinMirrorFlipConf) | |
| 361 lept_stderr("Text is not mirror reversed\n"); | |
| 362 if (*pconf < -DefaultMinMirrorFlipConf) | |
| 363 lept_stderr("Text is mirror reversed\n"); | |
| 364 } | |
| 365 | |
| 366 return 0; | |
| 367 } | |
| 368 | |
| 369 | |
| 370 /*---------------------------------------------------------------------* | |
| 371 * Auto-generated hmt code * | |
| 372 *---------------------------------------------------------------------*/ | |
| 373 /* | |
| 374 * pixFlipFHMTGen() | |
| 375 * | |
| 376 * Input: pixd (usual 3 choices: null, == pixs, != pixs) | |
| 377 * pixs | |
| 378 * sel name (one of four defined in SEL_NAMES[]) | |
| 379 * Return: pixd | |
| 380 * | |
| 381 * Notes: | |
| 382 * Action: hit-miss transform on pixs by the sel | |
| 383 * N.B.: the sel must have at least one hit, and it | |
| 384 * can have any number of misses. | |
| 385 */ | |
| 386 PIX * | |
| 387 pixFlipFHMTGen(PIX *pixd, | |
| 388 PIX *pixs, | |
| 389 const char *selname) | |
| 390 { | |
| 391 l_int32 i, index, found, w, h, wpls, wpld; | |
| 392 l_uint32 *datad, *datas, *datat; | |
| 393 PIX *pixt; | |
| 394 | |
| 395 if (!pixs) | |
| 396 return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd); | |
| 397 if (pixGetDepth(pixs) != 1) | |
| 398 return (PIX *)ERROR_PTR("pixs must be 1 bpp", __func__, pixd); | |
| 399 | |
| 400 found = FALSE; | |
| 401 for (i = 0; i < NUM_SELS_GENERATED; i++) { | |
| 402 if (strcmp(selname, SEL_NAMES[i]) == 0) { | |
| 403 found = TRUE; | |
| 404 index = i; | |
| 405 break; | |
| 406 } | |
| 407 } | |
| 408 if (found == FALSE) | |
| 409 return (PIX *)ERROR_PTR("sel index not found", __func__, pixd); | |
| 410 | |
| 411 if (pixd) { | |
| 412 if (!pixSizesEqual(pixs, pixd)) | |
| 413 return (PIX *)ERROR_PTR("sizes not equal", __func__, pixd); | |
| 414 } else { | |
| 415 if ((pixd = pixCreateTemplate(pixs)) == NULL) | |
| 416 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL); | |
| 417 } | |
| 418 | |
| 419 wpls = pixGetWpl(pixs); | |
| 420 wpld = pixGetWpl(pixd); | |
| 421 | |
| 422 /* The images must be surrounded with ADDED_BORDER white pixels, | |
| 423 * that we'll read from. We fabricate a "proper" | |
| 424 * image as the subimage within the border, having the | |
| 425 * following parameters: */ | |
| 426 w = pixGetWidth(pixs) - 2 * ADDED_BORDER; | |
| 427 h = pixGetHeight(pixs) - 2 * ADDED_BORDER; | |
| 428 datas = pixGetData(pixs) + ADDED_BORDER * wpls + ADDED_BORDER / 32; | |
| 429 datad = pixGetData(pixd) + ADDED_BORDER * wpld + ADDED_BORDER / 32; | |
| 430 | |
| 431 if (pixd == pixs) { /* need temp image if in-place */ | |
| 432 if ((pixt = pixCopy(NULL, pixs)) == NULL) | |
| 433 return (PIX *)ERROR_PTR("pixt not made", __func__, pixd); | |
| 434 datat = pixGetData(pixt) + ADDED_BORDER * wpls + ADDED_BORDER / 32; | |
| 435 flipfhmtgen_low(datad, w, h, wpld, datat, wpls, index); | |
| 436 pixDestroy(&pixt); | |
| 437 } else { /* simple and not in-place */ | |
| 438 flipfhmtgen_low(datad, w, h, wpld, datas, wpls, index); | |
| 439 } | |
| 440 | |
| 441 return pixd; | |
| 442 } | |
| 443 | |
| 444 | |
| 445 /*---------------------------------------------------------------------* | |
| 446 * Fast hmt dispatcher * | |
| 447 *---------------------------------------------------------------------*/ | |
| 448 /* | |
| 449 * flipfhmtgen_low() | |
| 450 * | |
| 451 * A dispatcher to appropriate low-level code for flip hmt ops | |
| 452 */ | |
| 453 static l_int32 | |
| 454 flipfhmtgen_low(l_uint32 *datad, | |
| 455 l_int32 w, | |
| 456 l_int32 h, | |
| 457 l_int32 wpld, | |
| 458 l_uint32 *datas, | |
| 459 l_int32 wpls, | |
| 460 l_int32 index) | |
| 461 { | |
| 462 | |
| 463 switch (index) | |
| 464 { | |
| 465 case 0: | |
| 466 fhmt_1_0(datad, w, h, wpld, datas, wpls); | |
| 467 break; | |
| 468 case 1: | |
| 469 fhmt_1_1(datad, w, h, wpld, datas, wpls); | |
| 470 break; | |
| 471 case 2: | |
| 472 fhmt_1_2(datad, w, h, wpld, datas, wpls); | |
| 473 break; | |
| 474 case 3: | |
| 475 fhmt_1_3(datad, w, h, wpld, datas, wpls); | |
| 476 break; | |
| 477 } | |
| 478 | |
| 479 return 0; | |
| 480 } | |
| 481 | |
| 482 | |
| 483 /*--------------------------------------------------------------------------* | |
| 484 * Low-level auto-generated hmt routines * | |
| 485 *--------------------------------------------------------------------------*/ | |
| 486 /* | |
| 487 * N.B. in all the low-level routines, the part of the image | |
| 488 * that is accessed has been clipped by ADDED_BORDER pixels | |
| 489 * on all four sides. This is done in the higher level | |
| 490 * code by redefining w and h smaller and by moving the | |
| 491 * start-of-image pointers up to the beginning of this | |
| 492 * interior rectangle. | |
| 493 */ | |
| 494 | |
| 495 static void | |
| 496 fhmt_1_0(l_uint32 *datad, | |
| 497 l_int32 w, | |
| 498 l_int32 h, | |
| 499 l_int32 wpld, | |
| 500 l_uint32 *datas, | |
| 501 l_int32 wpls) | |
| 502 { | |
| 503 l_int32 i; | |
| 504 l_int32 j, pwpls; | |
| 505 l_uint32 *sptr, *dptr; | |
| 506 l_int32 wpls2, wpls3; | |
| 507 | |
| 508 wpls2 = 2 * wpls; | |
| 509 wpls3 = 3 * wpls; | |
| 510 pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */ | |
| 511 | |
| 512 for (i = 0; i < h; i++) { | |
| 513 sptr = datas + i * wpls; | |
| 514 dptr = datad + i * wpld; | |
| 515 for (j = 0; j < pwpls; j++, sptr++, dptr++) { | |
| 516 *dptr = ((*(sptr - wpls) >> 3) | (*(sptr - wpls - 1) << 29)) & | |
| 517 (~*(sptr - wpls)) & | |
| 518 ((~*(sptr - wpls) << 1) | (~*(sptr - wpls + 1) >> 31)) & | |
| 519 ((*(sptr) >> 3) | (*(sptr - 1) << 29)) & | |
| 520 ((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) & | |
| 521 (~*sptr) & | |
| 522 ((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) & | |
| 523 ((*(sptr + wpls) >> 3) | (*(sptr + wpls - 1) << 29)) & | |
| 524 (~*(sptr + wpls)) & | |
| 525 ((*(sptr + wpls2) >> 3) | (*(sptr + wpls2 - 1) << 29)) & | |
| 526 ((*(sptr + wpls3) >> 3) | (*(sptr + wpls3 - 1) << 29)) & | |
| 527 ((*(sptr + wpls3) >> 2) | (*(sptr + wpls3 - 1) << 30)) & | |
| 528 ((*(sptr + wpls3) >> 1) | (*(sptr + wpls3 - 1) << 31)) & | |
| 529 (*(sptr + wpls3)) & | |
| 530 ((*(sptr + wpls3) << 1) | (*(sptr + wpls3 + 1) >> 31)) & | |
| 531 ((*(sptr + wpls3) << 2) | (*(sptr + wpls3 + 1) >> 30)); | |
| 532 } | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 | |
| 537 static void | |
| 538 fhmt_1_1(l_uint32 *datad, | |
| 539 l_int32 w, | |
| 540 l_int32 h, | |
| 541 l_int32 wpld, | |
| 542 l_uint32 *datas, | |
| 543 l_int32 wpls) | |
| 544 { | |
| 545 l_int32 i; | |
| 546 l_int32 j, pwpls; | |
| 547 l_uint32 *sptr, *dptr; | |
| 548 l_int32 wpls2, wpls3; | |
| 549 | |
| 550 wpls2 = 2 * wpls; | |
| 551 wpls3 = 3 * wpls; | |
| 552 pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */ | |
| 553 | |
| 554 for (i = 0; i < h; i++) { | |
| 555 sptr = datas + i * wpls; | |
| 556 dptr = datad + i * wpld; | |
| 557 for (j = 0; j < pwpls; j++, sptr++, dptr++) { | |
| 558 *dptr = ((~*(sptr - wpls) >> 1) | (~*(sptr - wpls - 1) << 31)) & | |
| 559 (~*(sptr - wpls)) & | |
| 560 ((*(sptr - wpls) << 3) | (*(sptr - wpls + 1) >> 29)) & | |
| 561 ((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) & | |
| 562 (~*sptr) & | |
| 563 ((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) & | |
| 564 ((*(sptr) << 3) | (*(sptr + 1) >> 29)) & | |
| 565 (~*(sptr + wpls)) & | |
| 566 ((*(sptr + wpls) << 3) | (*(sptr + wpls + 1) >> 29)) & | |
| 567 ((*(sptr + wpls2) << 3) | (*(sptr + wpls2 + 1) >> 29)) & | |
| 568 ((*(sptr + wpls3) >> 2) | (*(sptr + wpls3 - 1) << 30)) & | |
| 569 ((*(sptr + wpls3) >> 1) | (*(sptr + wpls3 - 1) << 31)) & | |
| 570 (*(sptr + wpls3)) & | |
| 571 ((*(sptr + wpls3) << 1) | (*(sptr + wpls3 + 1) >> 31)) & | |
| 572 ((*(sptr + wpls3) << 2) | (*(sptr + wpls3 + 1) >> 30)) & | |
| 573 ((*(sptr + wpls3) << 3) | (*(sptr + wpls3 + 1) >> 29)); | |
| 574 } | |
| 575 } | |
| 576 } | |
| 577 | |
| 578 | |
| 579 static void | |
| 580 fhmt_1_2(l_uint32 *datad, | |
| 581 l_int32 w, | |
| 582 l_int32 h, | |
| 583 l_int32 wpld, | |
| 584 l_uint32 *datas, | |
| 585 l_int32 wpls) | |
| 586 { | |
| 587 l_int32 i; | |
| 588 l_int32 j, pwpls; | |
| 589 l_uint32 *sptr, *dptr; | |
| 590 l_int32 wpls2, wpls3; | |
| 591 | |
| 592 wpls2 = 2 * wpls; | |
| 593 wpls3 = 3 * wpls; | |
| 594 pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */ | |
| 595 | |
| 596 for (i = 0; i < h; i++) { | |
| 597 sptr = datas + i * wpls; | |
| 598 dptr = datad + i * wpld; | |
| 599 for (j = 0; j < pwpls; j++, sptr++, dptr++) { | |
| 600 *dptr = ((*(sptr - wpls3) >> 3) | (*(sptr - wpls3 - 1) << 29)) & | |
| 601 ((*(sptr - wpls3) >> 2) | (*(sptr - wpls3 - 1) << 30)) & | |
| 602 ((*(sptr - wpls3) >> 1) | (*(sptr - wpls3 - 1) << 31)) & | |
| 603 (*(sptr - wpls3)) & | |
| 604 ((*(sptr - wpls3) << 1) | (*(sptr - wpls3 + 1) >> 31)) & | |
| 605 ((*(sptr - wpls3) << 2) | (*(sptr - wpls3 + 1) >> 30)) & | |
| 606 ((*(sptr - wpls2) >> 3) | (*(sptr - wpls2 - 1) << 29)) & | |
| 607 ((*(sptr - wpls) >> 3) | (*(sptr - wpls - 1) << 29)) & | |
| 608 (~*(sptr - wpls)) & | |
| 609 ((*(sptr) >> 3) | (*(sptr - 1) << 29)) & | |
| 610 ((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) & | |
| 611 (~*sptr) & | |
| 612 ((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) & | |
| 613 ((*(sptr + wpls) >> 3) | (*(sptr + wpls - 1) << 29)) & | |
| 614 (~*(sptr + wpls)) & | |
| 615 ((~*(sptr + wpls) << 1) | (~*(sptr + wpls + 1) >> 31)); | |
| 616 } | |
| 617 } | |
| 618 } | |
| 619 | |
| 620 | |
| 621 static void | |
| 622 fhmt_1_3(l_uint32 *datad, | |
| 623 l_int32 w, | |
| 624 l_int32 h, | |
| 625 l_int32 wpld, | |
| 626 l_uint32 *datas, | |
| 627 l_int32 wpls) | |
| 628 { | |
| 629 l_int32 i; | |
| 630 l_int32 j, pwpls; | |
| 631 l_uint32 *sptr, *dptr; | |
| 632 l_int32 wpls2, wpls3; | |
| 633 | |
| 634 wpls2 = 2 * wpls; | |
| 635 wpls3 = 3 * wpls; | |
| 636 pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */ | |
| 637 | |
| 638 for (i = 0; i < h; i++) { | |
| 639 sptr = datas + i * wpls; | |
| 640 dptr = datad + i * wpld; | |
| 641 for (j = 0; j < pwpls; j++, sptr++, dptr++) { | |
| 642 *dptr = ((*(sptr - wpls3) >> 2) | (*(sptr - wpls3 - 1) << 30)) & | |
| 643 ((*(sptr - wpls3) >> 1) | (*(sptr - wpls3 - 1) << 31)) & | |
| 644 (*(sptr - wpls3)) & | |
| 645 ((*(sptr - wpls3) << 1) | (*(sptr - wpls3 + 1) >> 31)) & | |
| 646 ((*(sptr - wpls3) << 2) | (*(sptr - wpls3 + 1) >> 30)) & | |
| 647 ((*(sptr - wpls3) << 3) | (*(sptr - wpls3 + 1) >> 29)) & | |
| 648 ((*(sptr - wpls2) << 3) | (*(sptr - wpls2 + 1) >> 29)) & | |
| 649 (~*(sptr - wpls)) & | |
| 650 ((*(sptr - wpls) << 3) | (*(sptr - wpls + 1) >> 29)) & | |
| 651 ((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) & | |
| 652 (~*sptr) & | |
| 653 ((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) & | |
| 654 ((*(sptr) << 3) | (*(sptr + 1) >> 29)) & | |
| 655 ((~*(sptr + wpls) >> 1) | (~*(sptr + wpls - 1) << 31)) & | |
| 656 (~*(sptr + wpls)) & | |
| 657 ((*(sptr + wpls) << 3) | (*(sptr + wpls + 1) >> 29)); | |
| 658 } | |
| 659 } | |
| 660 } |
