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 */
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  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  *------------------------------------------------------------------*/
134 PIX *
136  l_int32 factor)
137 {
138 l_uint8 sval;
139 l_uint16 *tab2;
140 l_int32 i, j, k, w, h, d, wd, hd, wpls, wpld, sdibits, sqbits, sbytes;
141 l_uint32 *datas, *datad, *lines, *lined, *tab4, *tab8;
142 PIX *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  *-------------------------------------------------------------------*/
228 static l_uint16 *
229 makeExpandTab2x(void)
230 {
231 l_uint16 *tab;
232 l_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 
257 static l_uint32 *
258 makeExpandTab4x(void)
259 {
260 l_uint32 *tab;
261 l_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 
286 static l_uint32 *
287 makeExpandTab8x(void)
288 {
289 l_uint32 *tab;
290 l_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_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
Definition: pix.h:139