Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
binexpand.c
Go to the documentation of this file.
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
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 */
52static l_uint16 * makeExpandTab2x(void);
53static l_uint32 * makeExpandTab4x(void);
54static l_uint32 * makeExpandTab8x(void);
55static l_uint32 expandtab16[] = {
56 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff};
57
58/*------------------------------------------------------------------*
59 * Replicated expansion (integer scaling) *
60 *------------------------------------------------------------------*/
69PIX *
71 l_int32 xfact,
72 l_int32 yfact)
73{
74l_int32 w, h, d, wd, hd, wpls, wpld, i, j, k, start;
75l_uint32 *datas, *datad, *lines, *lined;
76PIX *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 *------------------------------------------------------------------*/
132PIX *
134 l_int32 factor)
135{
136l_uint8 sval;
137l_uint16 *tab2;
138l_int32 i, j, k, w, h, d, wd, hd, wpls, wpld, sdibits, sqbits, sbytes;
139l_uint32 *datas, *datad, *lines, *lined, *tab4, *tab8;
140PIX *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 *-------------------------------------------------------------------*/
224static l_uint16 *
225makeExpandTab2x(void)
226{
227l_uint16 *tab;
228l_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
253static l_uint32 *
254makeExpandTab4x(void)
255{
256l_uint32 *tab;
257l_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
282static l_uint32 *
283makeExpandTab8x(void)
284{
285l_uint32 *tab;
286l_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}
#define GET_DATA_QBIT(pdata, n)
#define SET_DATA_BIT(pdata, n)
#define SET_DATA_TWO_BYTES(pdata, n, val)
#define GET_DATA_BYTE(pdata, n)
#define GET_DATA_DIBIT(pdata, n)
#define GET_DATA_BIT(pdata, n)
PIX * pixExpandBinaryReplicate(PIX *pixs, l_int32 xfact, l_int32 yfact)
pixExpandBinaryReplicate()
Definition binexpand.c:70
PIX * pixExpandBinaryPower2(PIX *pixs, l_int32 factor)
pixExpandBinaryPower2()
Definition binexpand.c:133