Leptonica  1.77.0
Image processing and image analysis suite
dwacomb.2.c
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 
34 #include <string.h>
35 #include "allheaders.h"
36 
37 PIX *pixMorphDwa_2(PIX *pixd, PIX *pixs, l_int32 operation, char *selname);
38 PIX *pixFMorphopGen_2(PIX *pixd, PIX *pixs, l_int32 operation, char *selname);
39 l_int32 fmorphopgen_low_2(l_uint32 *datad, l_int32 w,
40  l_int32 h, l_int32 wpld,
41  l_uint32 *datas, l_int32 wpls,
42  l_int32 index);
43 
44 static l_int32 NUM_SELS_GENERATED = 76;
45 static char SEL_NAMES[][80] = {
46  "sel_comb_4h",
47  "sel_comb_4v",
48  "sel_comb_5h",
49  "sel_comb_5v",
50  "sel_comb_6h",
51  "sel_comb_6v",
52  "sel_comb_7h",
53  "sel_comb_7v",
54  "sel_comb_8h",
55  "sel_comb_8v",
56  "sel_comb_9h",
57  "sel_comb_9v",
58  "sel_comb_10h",
59  "sel_comb_10v",
60  "sel_comb_12h",
61  "sel_comb_12v",
62  "sel_comb_14h",
63  "sel_comb_14v",
64  "sel_comb_15h",
65  "sel_comb_15v",
66  "sel_comb_16h",
67  "sel_comb_16v",
68  "sel_comb_18h",
69  "sel_comb_18v",
70  "sel_comb_20h",
71  "sel_comb_20v",
72  "sel_comb_21h",
73  "sel_comb_21v",
74  "sel_comb_22h",
75  "sel_comb_22v",
76  "sel_comb_24h",
77  "sel_comb_24v",
78  "sel_comb_25h",
79  "sel_comb_25v",
80  "sel_comb_27h",
81  "sel_comb_27v",
82  "sel_comb_28h",
83  "sel_comb_28v",
84  "sel_comb_30h",
85  "sel_comb_30v",
86  "sel_comb_32h",
87  "sel_comb_32v",
88  "sel_comb_33h",
89  "sel_comb_33v",
90  "sel_comb_35h",
91  "sel_comb_35v",
92  "sel_comb_36h",
93  "sel_comb_36v",
94  "sel_comb_39h",
95  "sel_comb_39v",
96  "sel_comb_40h",
97  "sel_comb_40v",
98  "sel_comb_42h",
99  "sel_comb_42v",
100  "sel_comb_44h",
101  "sel_comb_44v",
102  "sel_comb_45h",
103  "sel_comb_45v",
104  "sel_comb_48h",
105  "sel_comb_48v",
106  "sel_comb_49h",
107  "sel_comb_49v",
108  "sel_comb_50h",
109  "sel_comb_50v",
110  "sel_comb_52h",
111  "sel_comb_52v",
112  "sel_comb_54h",
113  "sel_comb_54v",
114  "sel_comb_55h",
115  "sel_comb_55v",
116  "sel_comb_56h",
117  "sel_comb_56v",
118  "sel_comb_60h",
119  "sel_comb_60v",
120  "sel_comb_63h",
121  "sel_comb_63v"};
122 
142 PIX *
143 pixMorphDwa_2(PIX *pixd,
144  PIX *pixs,
145  l_int32 operation,
146  char *selname)
147 {
148 l_int32 bordercolor, bordersize;
149 PIX *pixt1, *pixt2, *pixt3;
150 
151  PROCNAME("pixMorphDwa_2");
152 
153  if (!pixs)
154  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
155  if (pixGetDepth(pixs) != 1)
156  return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
157 
158  /* Set the border size */
159  bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
160  bordersize = 32;
161  if (bordercolor == 0 && operation == L_MORPH_CLOSE)
162  bordersize += 32;
163 
164  pixt1 = pixAddBorder(pixs, bordersize, 0);
165  pixt2 = pixFMorphopGen_2(NULL, pixt1, operation, selname);
166  pixt3 = pixRemoveBorder(pixt2, bordersize);
167  pixDestroy(&pixt1);
168  pixDestroy(&pixt2);
169 
170  if (!pixd)
171  return pixt3;
172 
173  pixCopy(pixd, pixt3);
174  pixDestroy(&pixt3);
175  return pixd;
176 }
177 
178 
202 PIX *
203 pixFMorphopGen_2(PIX *pixd,
204  PIX *pixs,
205  l_int32 operation,
206  char *selname)
207 {
208 l_int32 i, index, found, w, h, wpls, wpld, bordercolor, erodeop, borderop;
209 l_uint32 *datad, *datas, *datat;
210 PIX *pixt;
211 
212  PROCNAME("pixFMorphopGen_2");
213 
214  if (!pixs)
215  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
216  if (pixGetDepth(pixs) != 1)
217  return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
218 
219  /* Get boundary colors to use */
220  bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
221  if (bordercolor == 1)
222  erodeop = PIX_SET;
223  else
224  erodeop = PIX_CLR;
225 
226  found = FALSE;
227  for (i = 0; i < NUM_SELS_GENERATED; i++) {
228  if (strcmp(selname, SEL_NAMES[i]) == 0) {
229  found = TRUE;
230  index = 2 * i;
231  break;
232  }
233  }
234  if (found == FALSE)
235  return (PIX *)ERROR_PTR("sel index not found", procName, pixd);
236 
237  if (!pixd) {
238  if ((pixd = pixCreateTemplate(pixs)) == NULL)
239  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
240  }
241  else /* for in-place or pre-allocated */
242  pixResizeImageData(pixd, pixs);
243  wpls = pixGetWpl(pixs);
244  wpld = pixGetWpl(pixd);
245 
246  /* The images must be surrounded, in advance, with a border of
247  * size 32 pixels (or 64, for closing), that we'll read from.
248  * Fabricate a "proper" image as the subimage within the 32
249  * pixel border, having the following parameters: */
250  w = pixGetWidth(pixs) - 64;
251  h = pixGetHeight(pixs) - 64;
252  datas = pixGetData(pixs) + 32 * wpls + 1;
253  datad = pixGetData(pixd) + 32 * wpld + 1;
254 
255  if (operation == L_MORPH_DILATE || operation == L_MORPH_ERODE) {
256  borderop = PIX_CLR;
257  if (operation == L_MORPH_ERODE) {
258  borderop = erodeop;
259  index++;
260  }
261  if (pixd == pixs) { /* in-place; generate a temp image */
262  if ((pixt = pixCopy(NULL, pixs)) == NULL)
263  return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
264  datat = pixGetData(pixt) + 32 * wpls + 1;
265  pixSetOrClearBorder(pixt, 32, 32, 32, 32, borderop);
266  fmorphopgen_low_2(datad, w, h, wpld, datat, wpls, index);
267  pixDestroy(&pixt);
268  }
269  else { /* not in-place */
270  pixSetOrClearBorder(pixs, 32, 32, 32, 32, borderop);
271  fmorphopgen_low_2(datad, w, h, wpld, datas, wpls, index);
272  }
273  }
274  else { /* opening or closing; generate a temp image */
275  if ((pixt = pixCreateTemplate(pixs)) == NULL)
276  return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
277  datat = pixGetData(pixt) + 32 * wpls + 1;
278  if (operation == L_MORPH_OPEN) {
279  pixSetOrClearBorder(pixs, 32, 32, 32, 32, erodeop);
280  fmorphopgen_low_2(datat, w, h, wpls, datas, wpls, index+1);
281  pixSetOrClearBorder(pixt, 32, 32, 32, 32, PIX_CLR);
282  fmorphopgen_low_2(datad, w, h, wpld, datat, wpls, index);
283  }
284  else { /* closing */
285  pixSetOrClearBorder(pixs, 32, 32, 32, 32, PIX_CLR);
286  fmorphopgen_low_2(datat, w, h, wpls, datas, wpls, index);
287  pixSetOrClearBorder(pixt, 32, 32, 32, 32, erodeop);
288  fmorphopgen_low_2(datad, w, h, wpld, datat, wpls, index+1);
289  }
290  pixDestroy(&pixt);
291  }
292 
293  return pixd;
294 }
l_ok pixResizeImageData(PIX *pixd, const PIX *pixs)
pixResizeImageData()
Definition: pix1.c:696
l_int32 h
Definition: dewarp.h:164
#define PIX_CLR
Definition: pix.h:330
l_uint32 getMorphBorderPixelColor(l_int32 type, l_int32 depth)
getMorphBorderPixelColor()
Definition: morph.c:1708
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1624
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:367
l_ok pixSetOrClearBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixSetOrClearBorder()
Definition: pix2.c:1439
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition: pix2.c:1748
struct Pix * pixs
Definition: dewarp.h:154
PIX * pixRemoveBorder(PIX *pixs, l_int32 npix)
pixRemoveBorder()
Definition: pix2.c:1897
#define PIX_SET
Definition: pix.h:331
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
Definition: pix.h:134
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:628
l_int32 w
Definition: dewarp.h:163