Leptonica  1.77.0
Image processing and image analysis suite
binreduce.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 
43 #include <string.h>
44 #include "allheaders.h"
45 
46 
47 /*------------------------------------------------------------------*
48  * Subsampled reduction *
49  *------------------------------------------------------------------*/
70 PIX *
72  l_uint8 *intab)
73 {
74 l_uint8 byte0, byte1;
75 l_uint8 *tab;
76 l_uint16 shortd;
77 l_int32 i, id, j, ws, hs, wpls, wpld, wplsi;
78 l_uint32 word;
79 l_uint32 *datas, *datad, *lines, *lined;
80 PIX *pixd;
81 
82  PROCNAME("pixReduceBinary2");
83 
84  if (!pixs || pixGetDepth(pixs) != 1)
85  return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
86 
87  pixGetDimensions(pixs, &ws, &hs, NULL);
88  if (hs <= 1)
89  return (PIX *)ERROR_PTR("hs must be at least 2", procName, NULL);
90  wpls = pixGetWpl(pixs);
91  datas = pixGetData(pixs);
92 
93  if ((pixd = pixCreate(ws / 2, hs / 2, 1)) == NULL)
94  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
95  pixCopyResolution(pixd, pixs);
96  pixScaleResolution(pixd, 0.5, 0.5);
97  wpld = pixGetWpl(pixd);
98  datad = pixGetData(pixd);
99 
100  tab = (intab) ? intab : makeSubsampleTab2x();
101  if (!tab) {
102  pixDestroy(&pixd);
103  return (PIX *)ERROR_PTR("tab not made", procName, NULL);
104  }
105 
106  /* e.g., if ws = 65: wd = 32, wpls = 3, wpld = 1 --> trouble */
107  wplsi = L_MIN(wpls, 2 * wpld); /* iterate over this number of words */
108 
109  for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
110  lines = datas + i * wpls;
111  lined = datad + id * wpld;
112  for (j = 0; j < wplsi; j++) {
113  word = *(lines + j);
114  word = word & 0xaaaaaaaa; /* mask */
115  word = word | (word << 7); /* fold; data in bytes 0 & 2 */
116  byte0 = word >> 24;
117  byte1 = (word >> 8) & 0xff;
118  shortd = (tab[byte0] << 8) | tab[byte1];
119  SET_DATA_TWO_BYTES(lined, j, shortd);
120  }
121  }
122 
123  if (!intab) LEPT_FREE(tab);
124  return pixd;
125 }
126 
127 
128 /*------------------------------------------------------------------*
129  * Rank filtered binary reductions *
130  *------------------------------------------------------------------*/
147 PIX *
149  l_int32 level1,
150  l_int32 level2,
151  l_int32 level3,
152  l_int32 level4)
153 {
154 PIX *pix1, *pix2, *pix3, *pix4;
155 l_uint8 *tab;
156 
157  PROCNAME("pixReduceRankBinaryCascade");
158 
159  if (!pixs)
160  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
161  if (pixGetDepth(pixs) != 1)
162  return (PIX *)ERROR_PTR("pixs must be binary", procName, NULL);
163  if (level1 > 4 || level2 > 4 || level3 > 4 || level4 > 4)
164  return (PIX *)ERROR_PTR("levels must not exceed 4", procName, NULL);
165 
166  if (level1 <= 0) {
167  L_WARNING("no reduction because level1 not > 0\n", procName);
168  return pixCopy(NULL, pixs);
169  }
170 
171  if ((tab = makeSubsampleTab2x()) == NULL)
172  return (PIX *)ERROR_PTR("tab not made", procName, NULL);
173 
174  pix1 = pixReduceRankBinary2(pixs, level1, tab);
175  if (level2 <= 0) {
176  LEPT_FREE(tab);
177  return pix1;
178  }
179 
180  pix2 = pixReduceRankBinary2(pix1, level2, tab);
181  pixDestroy(&pix1);
182  if (level3 <= 0) {
183  LEPT_FREE(tab);
184  return pix2;
185  }
186 
187  pix3 = pixReduceRankBinary2(pix2, level3, tab);
188  pixDestroy(&pix2);
189  if (level4 <= 0) {
190  LEPT_FREE(tab);
191  return pix3;
192  }
193 
194  pix4 = pixReduceRankBinary2(pix3, level4, tab);
195  pixDestroy(&pix3);
196  LEPT_FREE(tab);
197  return pix4;
198 }
199 
200 
222 PIX *
224  l_int32 level,
225  l_uint8 *intab)
226 {
227 l_uint8 byte0, byte1;
228 l_uint8 *tab;
229 l_uint16 shortd;
230 l_int32 i, id, j, ws, hs, wpls, wpld, wplsi;
231 l_uint32 word1, word2, word3, word4;
232 l_uint32 *datas, *datad, *lines, *lined;
233 PIX *pixd;
234 
235  PROCNAME("pixReduceRankBinary2");
236 
237  if (!pixs)
238  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
239 
240  if (pixGetDepth(pixs) != 1)
241  return (PIX *)ERROR_PTR("pixs not binary", procName, NULL);
242  if (level < 1 || level > 4)
243  return (PIX *)ERROR_PTR("level must be in set {1,2,3,4}",
244  procName, NULL);
245 
246  pixGetDimensions(pixs, &ws, &hs, NULL);
247  if (hs <= 1)
248  return (PIX *)ERROR_PTR("hs must be at least 2", procName, NULL);
249  wpls = pixGetWpl(pixs);
250  datas = pixGetData(pixs);
251 
252  if ((pixd = pixCreate(ws / 2, hs / 2, 1)) == NULL)
253  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
254  pixCopyResolution(pixd, pixs);
255  pixScaleResolution(pixd, 0.5, 0.5);
256  wpld = pixGetWpl(pixd);
257  datad = pixGetData(pixd);
258 
259  tab = (intab) ? intab : makeSubsampleTab2x();
260  if (!tab) {
261  pixDestroy(&pixd);
262  return (PIX *)ERROR_PTR("tab not made", procName, NULL);
263  }
264 
265  /* e.g., if ws = 65: wd = 32, wpls = 3, wpld = 1 --> trouble */
266  wplsi = L_MIN(wpls, 2 * wpld); /* iterate over this number of words */
267 
268  switch (level)
269  {
270 
271  case 1:
272  for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
273  lines = datas + i * wpls;
274  lined = datad + id * wpld;
275  for (j = 0; j < wplsi; j++) {
276  word1 = *(lines + j);
277  word2 = *(lines + wpls + j);
278 
279  /* OR/OR */
280  word2 = word1 | word2;
281  word2 = word2 | (word2 << 1);
282 
283  word2 = word2 & 0xaaaaaaaa; /* mask */
284  word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */
285  byte0 = word1 >> 24;
286  byte1 = (word1 >> 8) & 0xff;
287  shortd = (tab[byte0] << 8) | tab[byte1];
288  SET_DATA_TWO_BYTES(lined, j, shortd);
289  }
290  }
291  break;
292 
293  case 2:
294  for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
295  lines = datas + i * wpls;
296  lined = datad + id * wpld;
297  for (j = 0; j < wplsi; j++) {
298  word1 = *(lines + j);
299  word2 = *(lines + wpls + j);
300 
301  /* (AND/OR) OR (OR/AND) */
302  word3 = word1 & word2;
303  word3 = word3 | (word3 << 1);
304  word4 = word1 | word2;
305  word4 = word4 & (word4 << 1);
306  word2 = word3 | word4;
307 
308  word2 = word2 & 0xaaaaaaaa; /* mask */
309  word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */
310  byte0 = word1 >> 24;
311  byte1 = (word1 >> 8) & 0xff;
312  shortd = (tab[byte0] << 8) | tab[byte1];
313  SET_DATA_TWO_BYTES(lined, j, shortd);
314  }
315  }
316  break;
317 
318  case 3:
319  for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
320  lines = datas + i * wpls;
321  lined = datad + id * wpld;
322  for (j = 0; j < wplsi; j++) {
323  word1 = *(lines + j);
324  word2 = *(lines + wpls + j);
325 
326  /* (AND/OR) AND (OR/AND) */
327  word3 = word1 & word2;
328  word3 = word3 | (word3 << 1);
329  word4 = word1 | word2;
330  word4 = word4 & (word4 << 1);
331  word2 = word3 & word4;
332 
333  word2 = word2 & 0xaaaaaaaa; /* mask */
334  word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */
335  byte0 = word1 >> 24;
336  byte1 = (word1 >> 8) & 0xff;
337  shortd = (tab[byte0] << 8) | tab[byte1];
338  SET_DATA_TWO_BYTES(lined, j, shortd);
339  }
340  }
341  break;
342 
343  case 4:
344  for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
345  lines = datas + i * wpls;
346  lined = datad + id * wpld;
347  for (j = 0; j < wplsi; j++) {
348  word1 = *(lines + j);
349  word2 = *(lines + wpls + j);
350 
351  /* AND/AND */
352  word2 = word1 & word2;
353  word2 = word2 & (word2 << 1);
354 
355  word2 = word2 & 0xaaaaaaaa; /* mask */
356  word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */
357  byte0 = word1 >> 24;
358  byte1 = (word1 >> 8) & 0xff;
359  shortd = (tab[byte0] << 8) | tab[byte1];
360  SET_DATA_TWO_BYTES(lined, j, shortd);
361  }
362  }
363  break;
364  }
365 
366  if (!intab) LEPT_FREE(tab);
367  return pixd;
368 }
369 
370 
383 l_uint8 *
385 {
386 l_uint8 *tab;
387 l_int32 i;
388 
389  PROCNAME("makeSubsampleTab2x");
390 
391  if ((tab = (l_uint8 *) LEPT_CALLOC(256, sizeof(l_uint8))) == NULL)
392  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
393 
394  for (i = 0; i < 256; i++)
395  tab[i] = ((i & 0x01) ) | /* 7 */
396  ((i & 0x04) >> 1) | /* 6 */
397  ((i & 0x10) >> 2) | /* 5 */
398  ((i & 0x40) >> 3) | /* 4 */
399  ((i & 0x02) << 3) | /* 3 */
400  ((i & 0x08) << 2) | /* 2 */
401  ((i & 0x20) << 1) | /* 1 */
402  ((i & 0x80) ); /* 0 */
403 
404  return tab;
405 }
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
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1065
PIX * pixReduceRankBinary2(PIX *pixs, l_int32 level, l_uint8 *intab)
pixReduceRankBinary2()
Definition: binreduce.c:223
PIX * pixReduceBinary2(PIX *pixs, l_uint8 *intab)
pixReduceBinary2()
Definition: binreduce.c:71
Definition: pix.h:134
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:628
PIX * pixReduceRankBinaryCascade(PIX *pixs, l_int32 level1, l_int32 level2, l_int32 level3, l_int32 level4)
pixReduceRankBinaryCascade()
Definition: binreduce.c:148
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
l_uint8 * makeSubsampleTab2x(void)
Permutation table for 2x rank binary reduction.
Definition: binreduce.c:384