Leptonica  1.83.1
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 */
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  *------------------------------------------------------------------*/
69 PIX *
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  *------------------------------------------------------------------*/
132 PIX *
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 }
#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:133
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1642
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1074
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:689
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315