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