Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/leptonica/src/binexpand.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 binexpand.c | |
| 29 * <pre> | |
| 30 * | |
| 31 * Replicated expansion (integer scaling) | |
| 32 * PIX *pixExpandBinaryReplicate() | |
| 33 * | |
| 34 * Special case: power of 2 replicated expansion | |
| 35 * PIX *pixExpandBinaryPower2() | |
| 36 * | |
| 37 * Expansion tables for power of 2 expansion | |
| 38 * static l_uint16 *makeExpandTab2x() | |
| 39 * static l_uint32 *makeExpandTab4x() | |
| 40 * static l_uint32 *makeExpandTab8x() | |
| 41 * </pre> | |
| 42 */ | |
| 43 | |
| 44 #ifdef HAVE_CONFIG_H | |
| 45 #include <config_auto.h> | |
| 46 #endif /* HAVE_CONFIG_H */ | |
| 47 | |
| 48 #include <string.h> | |
| 49 #include "allheaders.h" | |
| 50 | |
| 51 /* Static table functions and tables */ | |
| 52 static l_uint16 * makeExpandTab2x(void); | |
| 53 static l_uint32 * makeExpandTab4x(void); | |
| 54 static l_uint32 * makeExpandTab8x(void); | |
| 55 static l_uint32 expandtab16[] = { | |
| 56 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff}; | |
| 57 | |
| 58 /*------------------------------------------------------------------* | |
| 59 * Replicated expansion (integer scaling) * | |
| 60 *------------------------------------------------------------------*/ | |
| 61 /*! | |
| 62 * \brief pixExpandBinaryReplicate() | |
| 63 * | |
| 64 * \param[in] pixs 1 bpp | |
| 65 * \param[in] xfact integer scale factor for horiz. replicative expansion | |
| 66 * \param[in] yfact integer scale factor for vertical replicative expansion | |
| 67 * \return pixd scaled up, or NULL on error | |
| 68 */ | |
| 69 PIX * | |
| 70 pixExpandBinaryReplicate(PIX *pixs, | |
| 71 l_int32 xfact, | |
| 72 l_int32 yfact) | |
| 73 { | |
| 74 l_int32 w, h, d, wd, hd, wpls, wpld, i, j, k, start; | |
| 75 l_uint32 *datas, *datad, *lines, *lined; | |
| 76 PIX *pixd; | |
| 77 | |
| 78 if (!pixs) | |
| 79 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL); | |
| 80 pixGetDimensions(pixs, &w, &h, &d); | |
| 81 if (d != 1) | |
| 82 return (PIX *)ERROR_PTR("pixs not binary", __func__, NULL); | |
| 83 if (xfact <= 0 || yfact <= 0) | |
| 84 return (PIX *)ERROR_PTR("invalid scale factor: <= 0", __func__, NULL); | |
| 85 | |
| 86 if (xfact == yfact) { | |
| 87 if (xfact == 1) | |
| 88 return pixCopy(NULL, pixs); | |
| 89 if (xfact == 2 || xfact == 4 || xfact == 8 || xfact == 16) | |
| 90 return pixExpandBinaryPower2(pixs, xfact); | |
| 91 } | |
| 92 | |
| 93 wpls = pixGetWpl(pixs); | |
| 94 datas = pixGetData(pixs); | |
| 95 wd = xfact * w; | |
| 96 hd = yfact * h; | |
| 97 if ((pixd = pixCreate(wd, hd, 1)) == NULL) | |
| 98 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL); | |
| 99 pixCopyResolution(pixd, pixs); | |
| 100 pixScaleResolution(pixd, (l_float32)xfact, (l_float32)yfact); | |
| 101 wpld = pixGetWpl(pixd); | |
| 102 datad = pixGetData(pixd); | |
| 103 | |
| 104 for (i = 0; i < h; i++) { | |
| 105 lines = datas + i * wpls; | |
| 106 lined = datad + yfact * i * wpld; | |
| 107 for (j = 0; j < w; j++) { /* replicate pixels on a single line */ | |
| 108 if (GET_DATA_BIT(lines, j)) { | |
| 109 start = xfact * j; | |
| 110 for (k = 0; k < xfact; k++) | |
| 111 SET_DATA_BIT(lined, start + k); | |
| 112 } | |
| 113 } | |
| 114 for (k = 1; k < yfact; k++) /* replicate the line */ | |
| 115 memcpy(lined + k * wpld, lined, 4 * wpld); | |
| 116 } | |
| 117 | |
| 118 return pixd; | |
| 119 } | |
| 120 | |
| 121 | |
| 122 /*------------------------------------------------------------------* | |
| 123 * Power of 2 expansion * | |
| 124 *------------------------------------------------------------------*/ | |
| 125 /*! | |
| 126 * \brief pixExpandBinaryPower2() | |
| 127 * | |
| 128 * \param[in] pixs 1 bpp | |
| 129 * \param[in] factor expansion factor: 1, 2, 4, 8, 16 | |
| 130 * \return pixd expanded 1 bpp by replication, or NULL on error | |
| 131 */ | |
| 132 PIX * | |
| 133 pixExpandBinaryPower2(PIX *pixs, | |
| 134 l_int32 factor) | |
| 135 { | |
| 136 l_uint8 sval; | |
| 137 l_uint16 *tab2; | |
| 138 l_int32 i, j, k, w, h, d, wd, hd, wpls, wpld, sdibits, sqbits, sbytes; | |
| 139 l_uint32 *datas, *datad, *lines, *lined, *tab4, *tab8; | |
| 140 PIX *pixd; | |
| 141 | |
| 142 if (!pixs) | |
| 143 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL); | |
| 144 pixGetDimensions(pixs, &w, &h, &d); | |
| 145 if (d != 1) | |
| 146 return (PIX *)ERROR_PTR("pixs not binary", __func__, NULL); | |
| 147 if (factor == 1) | |
| 148 return pixCopy(NULL, pixs); | |
| 149 if (factor != 2 && factor != 4 && factor != 8 && factor != 16) | |
| 150 return (PIX *)ERROR_PTR("factor must be in {2,4,8,16}", __func__, NULL); | |
| 151 | |
| 152 wpls = pixGetWpl(pixs); | |
| 153 datas = pixGetData(pixs); | |
| 154 wd = factor * w; | |
| 155 hd = factor * h; | |
| 156 if ((pixd = pixCreate(wd, hd, 1)) == NULL) | |
| 157 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL); | |
| 158 pixCopyResolution(pixd, pixs); | |
| 159 pixScaleResolution(pixd, (l_float32)factor, (l_float32)factor); | |
| 160 wpld = pixGetWpl(pixd); | |
| 161 datad = pixGetData(pixd); | |
| 162 if (factor == 2) { | |
| 163 tab2 = makeExpandTab2x(); | |
| 164 sbytes = (w + 7) / 8; | |
| 165 for (i = 0; i < h; i++) { | |
| 166 lines = datas + i * wpls; | |
| 167 lined = datad + 2 * i * wpld; | |
| 168 for (j = 0; j < sbytes; j++) { | |
| 169 sval = GET_DATA_BYTE(lines, j); | |
| 170 SET_DATA_TWO_BYTES(lined, j, tab2[sval]); | |
| 171 } | |
| 172 memcpy(lined + wpld, lined, 4 * wpld); | |
| 173 } | |
| 174 LEPT_FREE(tab2); | |
| 175 } else if (factor == 4) { | |
| 176 tab4 = makeExpandTab4x(); | |
| 177 sbytes = (w + 7) / 8; | |
| 178 for (i = 0; i < h; i++) { | |
| 179 lines = datas + i * wpls; | |
| 180 lined = datad + 4 * i * wpld; | |
| 181 for (j = 0; j < sbytes; j++) { | |
| 182 sval = GET_DATA_BYTE(lines, j); | |
| 183 lined[j] = tab4[sval]; | |
| 184 } | |
| 185 for (k = 1; k < 4; k++) | |
| 186 memcpy(lined + k * wpld, lined, 4 * wpld); | |
| 187 } | |
| 188 LEPT_FREE(tab4); | |
| 189 } else if (factor == 8) { | |
| 190 tab8 = makeExpandTab8x(); | |
| 191 sqbits = (w + 3) / 4; | |
| 192 for (i = 0; i < h; i++) { | |
| 193 lines = datas + i * wpls; | |
| 194 lined = datad + 8 * i * wpld; | |
| 195 for (j = 0; j < sqbits; j++) { | |
| 196 sval = GET_DATA_QBIT(lines, j); | |
| 197 lined[j] = tab8[sval]; | |
| 198 } | |
| 199 for (k = 1; k < 8; k++) | |
| 200 memcpy(lined + k * wpld, lined, 4 * wpld); | |
| 201 } | |
| 202 LEPT_FREE(tab8); | |
| 203 } else { /* factor == 16 */ | |
| 204 sdibits = (w + 1) / 2; | |
| 205 for (i = 0; i < h; i++) { | |
| 206 lines = datas + i * wpls; | |
| 207 lined = datad + 16 * i * wpld; | |
| 208 for (j = 0; j < sdibits; j++) { | |
| 209 sval = GET_DATA_DIBIT(lines, j); | |
| 210 lined[j] = expandtab16[sval]; | |
| 211 } | |
| 212 for (k = 1; k < 16; k++) | |
| 213 memcpy(lined + k * wpld, lined, 4 * wpld); | |
| 214 } | |
| 215 } | |
| 216 | |
| 217 return pixd; | |
| 218 } | |
| 219 | |
| 220 | |
| 221 /*-------------------------------------------------------------------* | |
| 222 * Expansion tables for 2x, 4x and 8x expansion * | |
| 223 *-------------------------------------------------------------------*/ | |
| 224 static l_uint16 * | |
| 225 makeExpandTab2x(void) | |
| 226 { | |
| 227 l_uint16 *tab; | |
| 228 l_int32 i; | |
| 229 | |
| 230 tab = (l_uint16 *) LEPT_CALLOC(256, sizeof(l_uint16)); | |
| 231 for (i = 0; i < 256; i++) { | |
| 232 if (i & 0x01) | |
| 233 tab[i] = 0x3; | |
| 234 if (i & 0x02) | |
| 235 tab[i] |= 0xc; | |
| 236 if (i & 0x04) | |
| 237 tab[i] |= 0x30; | |
| 238 if (i & 0x08) | |
| 239 tab[i] |= 0xc0; | |
| 240 if (i & 0x10) | |
| 241 tab[i] |= 0x300; | |
| 242 if (i & 0x20) | |
| 243 tab[i] |= 0xc00; | |
| 244 if (i & 0x40) | |
| 245 tab[i] |= 0x3000; | |
| 246 if (i & 0x80) | |
| 247 tab[i] |= 0xc000; | |
| 248 } | |
| 249 return tab; | |
| 250 } | |
| 251 | |
| 252 | |
| 253 static l_uint32 * | |
| 254 makeExpandTab4x(void) | |
| 255 { | |
| 256 l_uint32 *tab; | |
| 257 l_int32 i; | |
| 258 | |
| 259 tab = (l_uint32 *) LEPT_CALLOC(256, sizeof(l_uint32)); | |
| 260 for (i = 0; i < 256; i++) { | |
| 261 if (i & 0x01) | |
| 262 tab[i] = 0xf; | |
| 263 if (i & 0x02) | |
| 264 tab[i] |= 0xf0; | |
| 265 if (i & 0x04) | |
| 266 tab[i] |= 0xf00; | |
| 267 if (i & 0x08) | |
| 268 tab[i] |= 0xf000; | |
| 269 if (i & 0x10) | |
| 270 tab[i] |= 0xf0000; | |
| 271 if (i & 0x20) | |
| 272 tab[i] |= 0xf00000; | |
| 273 if (i & 0x40) | |
| 274 tab[i] |= 0xf000000; | |
| 275 if (i & 0x80) | |
| 276 tab[i] |= 0xf0000000; | |
| 277 } | |
| 278 return tab; | |
| 279 } | |
| 280 | |
| 281 | |
| 282 static l_uint32 * | |
| 283 makeExpandTab8x(void) | |
| 284 { | |
| 285 l_uint32 *tab; | |
| 286 l_int32 i; | |
| 287 | |
| 288 tab = (l_uint32 *) LEPT_CALLOC(16, sizeof(l_uint32)); | |
| 289 for (i = 0; i < 16; i++) { | |
| 290 if (i & 0x01) | |
| 291 tab[i] = 0xff; | |
| 292 if (i & 0x02) | |
| 293 tab[i] |= 0xff00; | |
| 294 if (i & 0x04) | |
| 295 tab[i] |= 0xff0000; | |
| 296 if (i & 0x08) | |
| 297 tab[i] |= 0xff000000; | |
| 298 } | |
| 299 return tab; | |
| 300 } |
