comparison mupdf-source/thirdparty/leptonica/src/morphtemplate1.txt @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
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 * Top-level fast binary morphology with auto-generated sels
29 *
30 --- * PIX *pixMorphDwa_*()
31 --- * PIX *pixFMorphopGen_*()
32 */
33
34 #include <string.h>
35 #include "allheaders.h"
36
37 --- This file is: morphtemplate1.txt
38 ---
39 --- We need to include these prototypes:
40 --- PIX *pixMorphDwa_*(PIX *pixd, PIX *pixs, l_int32 operation,
41 --- char *selname);
42 --- PIX *pixFMorphopGen_*(PIX *pixd, PIX *pixs, l_int32 operation,
43 --- char *selname);
44 --- l_int32 fmorphopgen_low_*(l_uint32 *datad, l_int32 w, l_int32 h,
45 --- l_int32 wpld, l_uint32 *datas,
46 --- l_int32 wpls, l_int32 index);
47 ---
48 --- We need to input two static globals here:
49 --- static l_int32 NUM_SELS_GENERATED = <some number>;
50 --- static char SEL_NAMES[][80] = {"<string1>", "<string2>", ...};
51
52 /*!
53 --- * \brief pixMorphDwa_*()
54 *
55 * \param[in] pixd usual 3 choices: null, == pixs, != pixs
56 * \param[in] pixs 1 bpp
57 * \param[in] operation L_MORPH_DILATE, L_MORPH_ERODE,
58 * L_MORPH_OPEN, L_MORPH_CLOSE
59 * \param[in] sel name
60 * \return pixd
61 *
62 * <pre>
63 * Notes:
64 * (1) This simply adds a border, calls the appropriate
65 * pixFMorphopGen_*(), and removes the border.
66 * See the notes for that function.
67 * (2) The size of the border depends on the operation
68 * and the boundary conditions.
69 * </pre>
70 */
71 PIX *
72 --- pixMorphDwa_*(PIX *pixd,
73 PIX *pixs,
74 l_int32 operation,
75 char *selname)
76 {
77 l_int32 bordercolor, bordersize;
78 PIX *pixt1, *pixt2, *pixt3;
79
80 --- PROCNAME("pixMorpDwa_*");
81
82 if (!pixs)
83 return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd);
84 if (pixGetDepth(pixs) != 1)
85 return (PIX *)ERROR_PTR("pixs must be 1 bpp", __func__, pixd);
86
87 /* Set the border size */
88 bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
89 bordersize = 32;
90 if (bordercolor == 0 && operation == L_MORPH_CLOSE)
91 bordersize += 32;
92
93 pixt1 = pixAddBorder(pixs, bordersize, 0);
94 --- pixt2 = pixFMorphopGen_*(NULL, pixt1, operation, selname);
95 pixt3 = pixRemoveBorder(pixt2, bordersize);
96 pixDestroy(&pixt1);
97 pixDestroy(&pixt2);
98
99 if (!pixd)
100 return pixt3;
101
102 pixCopy(pixd, pixt3);
103 pixDestroy(&pixt3);
104 return pixd;
105 }
106
107
108 /*!
109 --- * \brief pixFMorphopGen_*()
110 *
111 * \param[in] pixd usual 3 choices: null, == pixs, != pixs
112 * \param[in] pixs 1 bpp
113 * \param[in] operation L_MORPH_DILATE, L_MORPH_ERODE,
114 * L_MORPH_OPEN, L_MORPH_CLOSE
115 * \param[in] sel name
116 * \return pixd
117 *
118 * <pre>
119 * Notes:
120 * (1) This is a dwa operation, and the Sels must be limited in
121 * size to not more than 31 pixels about the origin.
122 * (2) A border of appropriate size (32 pixels, or 64 pixels
123 * for safe closing with asymmetric b.c.) must be added before
124 * this function is called.
125 * (3) This handles all required setting of the border pixels
126 * before erosion and dilation.
127 * (4) The closing operation is safe; no pixels can be removed
128 * near the boundary.
129 * </pre>
130 */
131 PIX *
132 --- pixFMorphopGen_*(PIX *pixd,
133 PIX *pixs,
134 l_int32 operation,
135 char *selname)
136 {
137 l_int32 i, index, found, w, h, wpls, wpld, bordercolor, erodeop, borderop;
138 l_uint32 *datad, *datas, *datat;
139 PIX *pixt;
140
141 --- PROCNAME("pixFMorphopGen_*");
142
143 if (!pixs)
144 return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd);
145 if (pixGetDepth(pixs) != 1)
146 return (PIX *)ERROR_PTR("pixs must be 1 bpp", __func__, pixd);
147
148 /* Get boundary colors to use */
149 bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
150 if (bordercolor == 1)
151 erodeop = PIX_SET;
152 else
153 erodeop = PIX_CLR;
154
155 found = FALSE;
156 for (i = 0; i < NUM_SELS_GENERATED; i++) {
157 if (strcmp(selname, SEL_NAMES[i]) == 0) {
158 found = TRUE;
159 index = 2 * i;
160 break;
161 }
162 }
163 if (found == FALSE)
164 return (PIX *)ERROR_PTR("sel index not found", __func__, pixd);
165
166 if (!pixd) {
167 if ((pixd = pixCreateTemplate(pixs)) == NULL)
168 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
169 }
170 else /* for in-place or pre-allocated */
171 pixResizeImageData(pixd, pixs);
172 wpls = pixGetWpl(pixs);
173 wpld = pixGetWpl(pixd);
174
175 /* The images must be surrounded, in advance, with a border of
176 * size 32 pixels (or 64, for closing), that we'll read from.
177 * Fabricate a "proper" image as the subimage within the 32
178 * pixel border, having the following parameters: */
179 w = pixGetWidth(pixs) - 64;
180 h = pixGetHeight(pixs) - 64;
181 datas = pixGetData(pixs) + 32 * wpls + 1;
182 datad = pixGetData(pixd) + 32 * wpld + 1;
183
184 if (operation == L_MORPH_DILATE || operation == L_MORPH_ERODE) {
185 borderop = PIX_CLR;
186 if (operation == L_MORPH_ERODE) {
187 borderop = erodeop;
188 index++;
189 }
190 if (pixd == pixs) { /* in-place; generate a temp image */
191 if ((pixt = pixCopy(NULL, pixs)) == NULL)
192 return (PIX *)ERROR_PTR("pixt not made", __func__, pixd);
193 datat = pixGetData(pixt) + 32 * wpls + 1;
194 pixSetOrClearBorder(pixt, 32, 32, 32, 32, borderop);
195 --- fmorphopgen_low_*(datad, w, h, wpld, datat, wpls, index);
196 pixDestroy(&pixt);
197 }
198 else { /* not in-place */
199 pixSetOrClearBorder(pixs, 32, 32, 32, 32, borderop);
200 --- fmorphopgen_low_*(datad, w, h, wpld, datas, wpls, index);
201 }
202 }
203 else { /* opening or closing; generate a temp image */
204 if ((pixt = pixCreateTemplate(pixs)) == NULL)
205 return (PIX *)ERROR_PTR("pixt not made", __func__, pixd);
206 datat = pixGetData(pixt) + 32 * wpls + 1;
207 if (operation == L_MORPH_OPEN) {
208 pixSetOrClearBorder(pixs, 32, 32, 32, 32, erodeop);
209 --- fmorphopgen_low_*(datat, w, h, wpls, datas, wpls, index + 1);
210 pixSetOrClearBorder(pixt, 32, 32, 32, 32, PIX_CLR);
211 --- fmorphopgen_low_*(datad, w, h, wpld, datat, wpls, index);
212 }
213 else { /* closing */
214 pixSetOrClearBorder(pixs, 32, 32, 32, 32, PIX_CLR);
215 --- fmorphopgen_low_*(datat, w, h, wpls, datas, wpls, index);
216 pixSetOrClearBorder(pixt, 32, 32, 32, 32, erodeop);
217 --- fmorphopgen_low_*(datad, w, h, wpld, datat, wpls, index + 1);
218 }
219 pixDestroy(&pixt);
220 }
221
222 return pixd;
223 }
224