Leptonica 1.82.0
Image processing and image analysis suite
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 PROCNAME("pixExpandBinaryReplicate");
79
80 if (!pixs)
81 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
82 pixGetDimensions(pixs, &w, &h, &d);
83 if (d != 1)
84 return (PIX *)ERROR_PTR("pixs not binary", procName, NULL);
85 if (xfact <= 0 || yfact <= 0)
86 return (PIX *)ERROR_PTR("invalid scale factor: <= 0", procName, NULL);
87
88 if (xfact == yfact) {
89 if (xfact == 1)
90 return pixCopy(NULL, pixs);
91 if (xfact == 2 || xfact == 4 || xfact == 8 || xfact == 16)
92 return pixExpandBinaryPower2(pixs, xfact);
93 }
94
95 wpls = pixGetWpl(pixs);
96 datas = pixGetData(pixs);
97 wd = xfact * w;
98 hd = yfact * h;
99 if ((pixd = pixCreate(wd, hd, 1)) == NULL)
100 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
101 pixCopyResolution(pixd, pixs);
102 pixScaleResolution(pixd, (l_float32)xfact, (l_float32)yfact);
103 wpld = pixGetWpl(pixd);
104 datad = pixGetData(pixd);
105
106 for (i = 0; i < h; i++) {
107 lines = datas + i * wpls;
108 lined = datad + yfact * i * wpld;
109 for (j = 0; j < w; j++) { /* replicate pixels on a single line */
110 if (GET_DATA_BIT(lines, j)) {
111 start = xfact * j;
112 for (k = 0; k < xfact; k++)
113 SET_DATA_BIT(lined, start + k);
114 }
115 }
116 for (k = 1; k < yfact; k++) /* replicate the line */
117 memcpy(lined + k * wpld, lined, 4 * wpld);
118 }
119
120 return pixd;
121}
122
123
124/*------------------------------------------------------------------*
125 * Power of 2 expansion *
126 *------------------------------------------------------------------*/
134PIX *
136 l_int32 factor)
137{
138l_uint8 sval;
139l_uint16 *tab2;
140l_int32 i, j, k, w, h, d, wd, hd, wpls, wpld, sdibits, sqbits, sbytes;
141l_uint32 *datas, *datad, *lines, *lined, *tab4, *tab8;
142PIX *pixd;
143
144 PROCNAME("pixExpandBinaryPower2");
145
146 if (!pixs)
147 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
148 pixGetDimensions(pixs, &w, &h, &d);
149 if (d != 1)
150 return (PIX *)ERROR_PTR("pixs not binary", procName, NULL);
151 if (factor == 1)
152 return pixCopy(NULL, pixs);
153 if (factor != 2 && factor != 4 && factor != 8 && factor != 16)
154 return (PIX *)ERROR_PTR("factor must be in {2,4,8,16}", procName, NULL);
155
156 wpls = pixGetWpl(pixs);
157 datas = pixGetData(pixs);
158 wd = factor * w;
159 hd = factor * h;
160 if ((pixd = pixCreate(wd, hd, 1)) == NULL)
161 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
162 pixCopyResolution(pixd, pixs);
163 pixScaleResolution(pixd, (l_float32)factor, (l_float32)factor);
164 wpld = pixGetWpl(pixd);
165 datad = pixGetData(pixd);
166 if (factor == 2) {
167 tab2 = makeExpandTab2x();
168 sbytes = (w + 7) / 8;
169 for (i = 0; i < h; i++) {
170 lines = datas + i * wpls;
171 lined = datad + 2 * i * wpld;
172 for (j = 0; j < sbytes; j++) {
173 sval = GET_DATA_BYTE(lines, j);
174 SET_DATA_TWO_BYTES(lined, j, tab2[sval]);
175 }
176 memcpy(lined + wpld, lined, 4 * wpld);
177 }
178 LEPT_FREE(tab2);
179 } else if (factor == 4) {
180 tab4 = makeExpandTab4x();
181 sbytes = (w + 7) / 8;
182 for (i = 0; i < h; i++) {
183 lines = datas + i * wpls;
184 lined = datad + 4 * i * wpld;
185 for (j = 0; j < sbytes; j++) {
186 sval = GET_DATA_BYTE(lines, j);
187 lined[j] = tab4[sval];
188 }
189 for (k = 1; k < 4; k++)
190 memcpy(lined + k * wpld, lined, 4 * wpld);
191 }
192 LEPT_FREE(tab4);
193 } else if (factor == 8) {
194 tab8 = makeExpandTab8x();
195 sqbits = (w + 3) / 4;
196 for (i = 0; i < h; i++) {
197 lines = datas + i * wpls;
198 lined = datad + 8 * i * wpld;
199 for (j = 0; j < sqbits; j++) {
200 sval = GET_DATA_QBIT(lines, j);
201 lined[j] = tab8[sval];
202 }
203 for (k = 1; k < 8; k++)
204 memcpy(lined + k * wpld, lined, 4 * wpld);
205 }
206 LEPT_FREE(tab8);
207 } else { /* factor == 16 */
208 sdibits = (w + 1) / 2;
209 for (i = 0; i < h; i++) {
210 lines = datas + i * wpls;
211 lined = datad + 16 * i * wpld;
212 for (j = 0; j < sdibits; j++) {
213 sval = GET_DATA_DIBIT(lines, j);
214 lined[j] = expandtab16[sval];
215 }
216 for (k = 1; k < 16; k++)
217 memcpy(lined + k * wpld, lined, 4 * wpld);
218 }
219 }
220
221 return pixd;
222}
223
224
225/*-------------------------------------------------------------------*
226 * Expansion tables for 2x, 4x and 8x expansion *
227 *-------------------------------------------------------------------*/
228static l_uint16 *
229makeExpandTab2x(void)
230{
231l_uint16 *tab;
232l_int32 i;
233
234 tab = (l_uint16 *) LEPT_CALLOC(256, sizeof(l_uint16));
235 for (i = 0; i < 256; i++) {
236 if (i & 0x01)
237 tab[i] = 0x3;
238 if (i & 0x02)
239 tab[i] |= 0xc;
240 if (i & 0x04)
241 tab[i] |= 0x30;
242 if (i & 0x08)
243 tab[i] |= 0xc0;
244 if (i & 0x10)
245 tab[i] |= 0x300;
246 if (i & 0x20)
247 tab[i] |= 0xc00;
248 if (i & 0x40)
249 tab[i] |= 0x3000;
250 if (i & 0x80)
251 tab[i] |= 0xc000;
252 }
253 return tab;
254}
255
256
257static l_uint32 *
258makeExpandTab4x(void)
259{
260l_uint32 *tab;
261l_int32 i;
262
263 tab = (l_uint32 *) LEPT_CALLOC(256, sizeof(l_uint32));
264 for (i = 0; i < 256; i++) {
265 if (i & 0x01)
266 tab[i] = 0xf;
267 if (i & 0x02)
268 tab[i] |= 0xf0;
269 if (i & 0x04)
270 tab[i] |= 0xf00;
271 if (i & 0x08)
272 tab[i] |= 0xf000;
273 if (i & 0x10)
274 tab[i] |= 0xf0000;
275 if (i & 0x20)
276 tab[i] |= 0xf00000;
277 if (i & 0x40)
278 tab[i] |= 0xf000000;
279 if (i & 0x80)
280 tab[i] |= 0xf0000000;
281 }
282 return tab;
283}
284
285
286static l_uint32 *
287makeExpandTab8x(void)
288{
289l_uint32 *tab;
290l_int32 i;
291
292 tab = (l_uint32 *) LEPT_CALLOC(16, sizeof(l_uint32));
293 for (i = 0; i < 16; i++) {
294 if (i & 0x01)
295 tab[i] = 0xff;
296 if (i & 0x02)
297 tab[i] |= 0xff00;
298 if (i & 0x04)
299 tab[i] |= 0xff0000;
300 if (i & 0x08)
301 tab[i] |= 0xff000000;
302 }
303 return tab;
304}
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:164
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:127
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
#define GET_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:145
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
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:135
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
Definition: pix.h:139