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 }