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
27 /*!
28 * \brief Top-level fast hit-miss transform with auto-generated sels
29 *
30 * PIX *pixHMTDwa_1()
31 * PIX *pixFHMTGen_1()
32 */
33
34 #include <string.h>
35 #include "allheaders.h"
36
37 PIX *pixHMTDwa_1(PIX *pixd, PIX *pixs, const char *selname);
38 PIX *pixFHMTGen_1(PIX *pixd, PIX *pixs, const char *selname);
39 l_int32 fhmtgen_low_1(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 = 10;
45 static char SEL_NAMES[][80] = {
46 "sel_3hm",
47 "sel_3de",
48 "sel_3ue",
49 "sel_3re",
50 "sel_3le",
51 "sel_sl1",
52 "sel_ulc",
53 "sel_urc",
54 "sel_llc",
55 "sel_lrc"};
56
57 /*!
58 * \brief pixHMTDwa_1()
59 *
60 * \param[in] pixd usual 3 choices: null, == pixs, != pixs
61 * \param[in] pixs 1 bpp
62 * \param[in] sel name
63 * \return pixd
64 *
65 * <pre>
66 * Notes:
67 * (1) This simply adds a 32 pixel border, calls the appropriate
68 * pixFHMTGen_*(), and removes the border.
69 * See notes below for that function.
70 * </pre>
71 */
72 PIX *
pixHMTDwa_1(PIX * pixd,PIX * pixs,const char * selname)73 pixHMTDwa_1(PIX *pixd,
74 PIX *pixs,
75 const char *selname)
76 {
77 PIX *pixt1, *pixt2, *pixt3;
78
79 PROCNAME("pixHMTDwa_1");
80
81 if (!pixs)
82 return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
83 if (pixGetDepth(pixs) != 1)
84 return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
85
86 pixt1 = pixAddBorder(pixs, 32, 0);
87 pixt2 = pixFHMTGen_1(NULL, pixt1, selname);
88 pixt3 = pixRemoveBorder(pixt2, 32);
89 pixDestroy(&pixt1);
90 pixDestroy(&pixt2);
91
92 if (!pixd)
93 return pixt3;
94
95 pixCopy(pixd, pixt3);
96 pixDestroy(&pixt3);
97 return pixd;
98 }
99
100
101 /*!
102 * \brief pixFHMTGen_1()
103 *
104 * \param[in] pixd usual 3 choices: null, == pixs, != pixs
105 * \param[in] pixs 1 bpp
106 * \param[in] sel name
107 * \return pixd
108 *
109 * <pre>
110 * Notes:
111 * (1) This is a dwa implementation of the hit-miss transform
112 * on pixs by the sel.
113 * (2) The sel must be limited in size to not more than 31 pixels
114 * about the origin. It must have at least one hit, and it
115 * can have any number of misses.
116 * (3) This handles all required setting of the border pixels
117 * before erosion and dilation.
118 * </pre>
119 */
120 PIX *
pixFHMTGen_1(PIX * pixd,PIX * pixs,const char * selname)121 pixFHMTGen_1(PIX *pixd,
122 PIX *pixs,
123 const char *selname)
124 {
125 l_int32 i, index, found, w, h, wpls, wpld;
126 l_uint32 *datad, *datas, *datat;
127 PIX *pixt;
128
129 PROCNAME("pixFHMTGen_1");
130
131 if (!pixs)
132 return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
133 if (pixGetDepth(pixs) != 1)
134 return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
135
136 found = FALSE;
137 for (i = 0; i < NUM_SELS_GENERATED; i++) {
138 if (strcmp(selname, SEL_NAMES[i]) == 0) {
139 found = TRUE;
140 index = i;
141 break;
142 }
143 }
144 if (found == FALSE)
145 return (PIX *)ERROR_PTR("sel index not found", procName, pixd);
146
147 if (!pixd) {
148 if ((pixd = pixCreateTemplate(pixs)) == NULL)
149 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
150 }
151 else /* for in-place or pre-allocated */
152 pixResizeImageData(pixd, pixs);
153 wpls = pixGetWpl(pixs);
154 wpld = pixGetWpl(pixd);
155
156 /* The images must be surrounded with 32 additional border
157 * pixels, that we'll read from. We fabricate a "proper"
158 * image as the subimage within the border, having the
159 * following parameters: */
160 w = pixGetWidth(pixs) - 64;
161 h = pixGetHeight(pixs) - 64;
162 datas = pixGetData(pixs) + 32 * wpls + 1;
163 datad = pixGetData(pixd) + 32 * wpld + 1;
164
165 if (pixd == pixs) { /* need temp image if in-place */
166 if ((pixt = pixCopy(NULL, pixs)) == NULL)
167 return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
168 datat = pixGetData(pixt) + 32 * wpls + 1;
169 fhmtgen_low_1(datad, w, h, wpld, datat, wpls, index);
170 pixDestroy(&pixt);
171 }
172 else { /* not in-place */
173 fhmtgen_low_1(datad, w, h, wpld, datas, wpls, index);
174 }
175
176 return pixd;
177 }
178