1 /*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 - This software is distributed in the hope that it will be
4 - useful, but with NO WARRANTY OF ANY KIND.
5 - No author or distributor accepts responsibility to anyone for the
6 - consequences of using this software, or for whether it serves any
7 - particular purpose or works at all, unless he or she says so in
8 - writing. Everyone is granted permission to copy, modify and
9 - redistribute this source code, for commercial or non-commercial
10 - purposes, with the following restrictions: (1) the origin of this
11 - source code must not be misrepresented; (2) modified versions must
12 - be plainly marked as such; and (3) this notice may not be removed
13 - or altered from any source or modified source distribution.
14 *====================================================================*/
15
16 /*
17 * binreduce.c
18 *
19 * Subsampled reduction
20 *
21 * PIX *pixReduceBinary2()
22 *
23 * Rank filtered reductions
24 *
25 * PIX *pixReduceRankBinaryCascade()
26 * PIX *pixReduceRankBinary2()
27 */
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include "allheaders.h"
33
34
35 /*------------------------------------------------------------------*
36 * Subsampled reduction *
37 *------------------------------------------------------------------*/
38 /*!
39 * pixReduceBinary2()
40 *
41 * Input: pixs
42 * tab (<optional>; if null, a table is made here
43 * and destroyed before exit)
44 * Return: pixd (2x subsampled), or null on error
45 */
46 PIX *
pixReduceBinary2(PIX * pixs,l_uint8 * intab)47 pixReduceBinary2(PIX *pixs,
48 l_uint8 *intab)
49 {
50 l_uint8 *tab;
51 l_int32 ws, hs, wpls, wpld;
52 l_uint32 *datas, *datad;
53 PIX *pixd;
54
55 PROCNAME("pixReduceBinary2");
56
57 if (!pixs)
58 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
59
60 if (pixGetDepth(pixs) != 1)
61 return (PIX *)ERROR_PTR("pixs not binary", procName, NULL);
62
63 if (intab) /* use input table */
64 tab = intab;
65 else {
66 if ((tab = makeSubsampleTab2x()) == NULL)
67 return (PIX *)ERROR_PTR("tab not made", procName, NULL);
68 }
69
70 ws = pixGetWidth(pixs);
71 hs = pixGetHeight(pixs);
72 if (hs <= 1)
73 return (PIX *)ERROR_PTR("hs must be at least 2", procName, NULL);
74 wpls = pixGetWpl(pixs);
75 datas = pixGetData(pixs);
76
77 if ((pixd = pixCreate(ws / 2, hs / 2, 1)) == NULL)
78 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
79 pixCopyResolution(pixd, pixs);
80 pixScaleResolution(pixd, 0.5, 0.5);
81 wpld = pixGetWpl(pixd);
82 datad = pixGetData(pixd);
83
84 reduceBinary2Low(datad, wpld, datas, hs, wpls, tab);
85
86 if (intab == NULL)
87 FREE(tab);
88
89 return pixd;
90 }
91
92
93 /*------------------------------------------------------------------*
94 * Rank filtered binary reductions *
95 *------------------------------------------------------------------*/
96 /*!
97 * pixReduceRankBinaryCascade()
98 *
99 * Input: pixs (1 bpp)
100 * level1, ... level 4 (thresholds, in the set {0, 1, 2, 3, 4})
101 * Return: pixd, or null on error
102 *
103 * Notes:
104 * (1) This performs up to four cascaded 2x rank reductions.
105 * (2) Use level = 0 to truncate the cascade.
106 */
107 PIX *
pixReduceRankBinaryCascade(PIX * pixs,l_int32 level1,l_int32 level2,l_int32 level3,l_int32 level4)108 pixReduceRankBinaryCascade(PIX *pixs,
109 l_int32 level1,
110 l_int32 level2,
111 l_int32 level3,
112 l_int32 level4)
113 {
114 PIX *pix1, *pix2, *pix3, *pix4;
115 l_uint8 *tab;
116
117 PROCNAME("pixReduceRankBinaryCascade");
118
119 if (!pixs)
120 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
121 if (pixGetDepth(pixs) != 1)
122 return (PIX *)ERROR_PTR("pixs must be binary", procName, NULL);
123 if (level1 > 4 || level2 > 4 || level3 > 4 || level4 > 4)
124 return (PIX *)ERROR_PTR("levels must not exceed 4", procName, NULL);
125
126 if (level1 <= 0) {
127 L_WARNING("no reduction because level1 not > 0", procName);
128 return pixCopy(NULL, pixs);
129 }
130
131 if ((tab = makeSubsampleTab2x()) == NULL)
132 return (PIX *)ERROR_PTR("tab not made", procName, NULL);
133
134 pix1 = pixReduceRankBinary2(pixs, level1, tab);
135 if (level2 <= 0) {
136 FREE(tab);
137 return pix1;
138 }
139
140 pix2 = pixReduceRankBinary2(pix1, level2, tab);
141 pixDestroy(&pix1);
142 if (level3 <= 0) {
143 FREE(tab);
144 return pix2;
145 }
146
147 pix3 = pixReduceRankBinary2(pix2, level3, tab);
148 pixDestroy(&pix2);
149 if (level4 <= 0) {
150 FREE(tab);
151 return pix3;
152 }
153
154 pix4 = pixReduceRankBinary2(pix3, level4, tab);
155 pixDestroy(&pix3);
156 FREE(tab);
157 return pix4;
158 }
159
160
161 /*!
162 * pixReduceRankBinary2()
163 *
164 * Input: pixs (1 bpp)
165 * level (rank threshold: 1, 2, 3, 4)
166 * intab (<optional>; if null, a table is made here
167 * and destroyed before exit)
168 * Return: pixd (1 bpp, 2x rank threshold reduced), or null on error
169 *
170 * Notes:
171 * (1) pixd is downscaled by 2x from pixs.
172 * (2) The rank threshold specifies the minimum number of ON
173 * pixels in each 2x2 region of pixs that are required to
174 * set the corresponding pixel ON in pixd.
175 */
176 PIX *
pixReduceRankBinary2(PIX * pixs,l_int32 level,l_uint8 * intab)177 pixReduceRankBinary2(PIX *pixs,
178 l_int32 level,
179 l_uint8 *intab)
180 {
181 l_uint8 *tab;
182 l_int32 ws, hs, wpls, wpld;
183 l_uint32 *datas, *datad;
184 PIX *pixd;
185
186 PROCNAME("pixReduceRankBinary2");
187
188 if (!pixs)
189 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
190
191 if (pixGetDepth(pixs) != 1)
192 return (PIX *)ERROR_PTR("pixs not binary", procName, NULL);
193 if (level < 1 || level > 4)
194 return (PIX *)ERROR_PTR("level must be in set {1,2,3,4}",
195 procName, NULL);
196
197 if (intab) /* use input table */
198 tab = intab;
199 else {
200 if ((tab = makeSubsampleTab2x()) == NULL)
201 return (PIX *)ERROR_PTR("tab not made", procName, NULL);
202 }
203
204 ws = pixGetWidth(pixs);
205 hs = pixGetHeight(pixs);
206 if (hs <= 1)
207 return (PIX *)ERROR_PTR("hs must be at least 2", procName, NULL);
208 wpls = pixGetWpl(pixs);
209 datas = pixGetData(pixs);
210
211 if ((pixd = pixCreate(ws / 2, hs / 2, 1)) == NULL)
212 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
213 pixCopyResolution(pixd, pixs);
214 pixScaleResolution(pixd, 0.5, 0.5);
215 wpld = pixGetWpl(pixd);
216 datad = pixGetData(pixd);
217
218 reduceRankBinary2Low(datad, wpld, datas, hs, wpls, tab, level);
219
220 if (!intab)
221 FREE(tab);
222
223 return pixd;
224 }
225
226
227